コード例 #1
0
ファイル: dh_ameth.c プロジェクト: busterb/libssl-openbsd
static int
do_dh_print(BIO *bp, const DH *x, int indent, ASN1_PCTX *ctx, int ptype)
{
	unsigned char *m = NULL;
	int reason = ERR_R_BUF_LIB, ret = 0;
	size_t buf_len = 0;
	const char *ktype = NULL;
	BIGNUM *priv_key, *pub_key;

	if (ptype == 2)
		priv_key = x->priv_key;
	else
		priv_key = NULL;

	if (ptype > 0)
		pub_key = x->pub_key;
	else
		pub_key = NULL;

	update_buflen(x->p, &buf_len);

	if (buf_len == 0) {
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
	}

	update_buflen(x->g, &buf_len);
	update_buflen(pub_key, &buf_len);
	update_buflen(priv_key, &buf_len);

	if (ptype == 2)
		ktype = "PKCS#3 DH Private-Key";
	else if (ptype == 1)
		ktype = "PKCS#3 DH Public-Key";
	else
		ktype = "PKCS#3 DH Parameters";

	m= malloc(buf_len + 10);
	if (m == NULL) {
		reason = ERR_R_MALLOC_FAILURE;
		goto err;
	}

	BIO_indent(bp, indent, 128);
	if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
		goto err;
	indent += 4;

	if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent))
		goto err;
	if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent))
		goto err;

	if (!ASN1_bn_print(bp, "prime:", x->p, m, indent))
		goto err;
	if (!ASN1_bn_print(bp, "generator:", x->g, m, indent))
		goto err;
	if (x->length != 0) {
		BIO_indent(bp, indent, 128);
		if (BIO_printf(bp, "recommended-private-length: %d bits\n",
		    (int)x->length) <= 0)
			goto err;
	}

	ret = 1;
	if (0) {
err:
		DHerr(DH_F_DO_DH_PRINT,reason);
	}
	free(m);
	return(ret);
}
コード例 #2
0
/*
 * read packets, try to authenticate the user and
 * return only if authentication is successful
 */
static void
do_authloop(Authctxt *authctxt)
{
	int authenticated = 0;
	u_int bits;
	Key *client_host_key;
	BIGNUM *n;
	char *client_user, *password;
	char info[1024];
	u_int dlen;
	u_int ulen;
	int type = 0;
	struct passwd *pw = authctxt->pw;

	debug("Attempting authentication for %s%.100s.",
	    authctxt->valid ? "" : "illegal user ", authctxt->user);

	/* If the user has no password, accept authentication immediately. */
	if (options.password_authentication &&
#if defined(KRB4) || defined(KRB5)
	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif
	    PRIVSEP(auth_password(authctxt, ""))) {
		auth_log(authctxt, 1, "without authentication", "");
		return;
	}

	/* Indicate that authentication is needed. */
	packet_start(SSH_SMSG_FAILURE);
	packet_send();
	packet_write_wait();

	client_user = NULL;

	for (;;) {
		/* default to fail */
		authenticated = 0;

		info[0] = '\0';

		/* Get a packet from the client. */
		type = packet_read();

		/* Process the packet. */
		switch (type) {

#if defined(KRB4) || defined(KRB5)
		case SSH_CMSG_AUTH_KERBEROS:
			if (!options.kerberos_authentication) {
				verbose("Kerberos authentication disabled.");
			} else {
				char *kdata = packet_get_string(&dlen);
				packet_check_eom();

				if (kdata[0] == 4) { /* KRB_PROT_VERSION */
#ifdef KRB4
					KTEXT_ST tkt, reply;
					tkt.length = dlen;
					if (tkt.length < MAX_KTXT_LEN)
						memcpy(tkt.dat, kdata, tkt.length);

					if (PRIVSEP(auth_krb4(authctxt, &tkt,
					    &client_user, &reply))) {
						authenticated = 1;
						snprintf(info, sizeof(info),
						    " tktuser %.100s",
						    client_user);

						packet_start(
						    SSH_SMSG_AUTH_KERBEROS_RESPONSE);
						packet_put_string((char *)
						    reply.dat, reply.length);
						packet_send();
						packet_write_wait();
					}
#endif /* KRB4 */
				} else {
#ifdef KRB5
					krb5_data tkt, reply;
					tkt.length = dlen;
					tkt.data = kdata;

					if (PRIVSEP(auth_krb5(authctxt, &tkt,
					    &client_user, &reply))) {
						authenticated = 1;
						snprintf(info, sizeof(info),
						    " tktuser %.100s",
						    client_user);

 						/* Send response to client */
 						packet_start(
						    SSH_SMSG_AUTH_KERBEROS_RESPONSE);
 						packet_put_string((char *)
						    reply.data, reply.length);
 						packet_send();
 						packet_write_wait();

 						if (reply.length)
 							xfree(reply.data);
					}
#endif /* KRB5 */
				}
				xfree(kdata);
			}
			break;
#endif /* KRB4 || KRB5 */

#if defined(AFS) || defined(KRB5)
			/* XXX - punt on backward compatibility here. */
		case SSH_CMSG_HAVE_KERBEROS_TGT:
			packet_send_debug("Kerberos TGT passing disabled before authentication.");
			break;
#ifdef AFS
		case SSH_CMSG_HAVE_AFS_TOKEN:
			packet_send_debug("AFS token passing disabled before authentication.");
			break;
#endif /* AFS */
#endif /* AFS || KRB5 */

		case SSH_CMSG_AUTH_RHOSTS:
			if (!options.rhosts_authentication) {
				verbose("Rhosts authentication disabled.");
				break;
			}
			/*
			 * Get client user name.  Note that we just have to
			 * trust the client; this is one reason why rhosts
			 * authentication is insecure. (Another is
			 * IP-spoofing on a local network.)
			 */
			client_user = packet_get_string(&ulen);
			packet_check_eom();

			/* Try to authenticate using /etc/hosts.equiv and .rhosts. */
			authenticated = auth_rhosts(pw, client_user);

			snprintf(info, sizeof info, " ruser %.100s", client_user);
			break;

		case SSH_CMSG_AUTH_RHOSTS_RSA:
			if (!options.rhosts_rsa_authentication) {
				verbose("Rhosts with RSA authentication disabled.");
				break;
			}
			/*
			 * Get client user name.  Note that we just have to
			 * trust the client; root on the client machine can
			 * claim to be any user.
			 */
			client_user = packet_get_string(&ulen);

			/* Get the client host key. */
			client_host_key = key_new(KEY_RSA1);
			bits = packet_get_int();
			packet_get_bignum(client_host_key->rsa->e);
			packet_get_bignum(client_host_key->rsa->n);

			if (bits != BN_num_bits(client_host_key->rsa->n))
				verbose("Warning: keysize mismatch for client_host_key: "
				    "actual %d, announced %d",
				    BN_num_bits(client_host_key->rsa->n), bits);
			packet_check_eom();

			authenticated = auth_rhosts_rsa(pw, client_user,
			    client_host_key);
			key_free(client_host_key);

			snprintf(info, sizeof info, " ruser %.100s", client_user);
			break;

		case SSH_CMSG_AUTH_RSA:
			if (!options.rsa_authentication) {
				verbose("RSA authentication disabled.");
				break;
			}
			/* RSA authentication requested. */
			if ((n = BN_new()) == NULL)
				fatal("do_authloop: BN_new failed");
			packet_get_bignum(n);
			packet_check_eom();
			authenticated = auth_rsa(pw, n);
			BN_clear_free(n);
			break;

		case SSH_CMSG_AUTH_PASSWORD:
			if (!options.password_authentication) {
				verbose("Password authentication disabled.");
				break;
			}
			/*
			 * Read user password.  It is in plain text, but was
			 * transmitted over the encrypted channel so it is
			 * not visible to an outside observer.
			 */
			password = packet_get_string(&dlen);
			packet_check_eom();

			/* Try authentication with the password. */
			authenticated = PRIVSEP(auth_password(authctxt, password));

			memset(password, 0, strlen(password));
			xfree(password);
			break;

		case SSH_CMSG_AUTH_TIS:
			debug("rcvd SSH_CMSG_AUTH_TIS");
			if (options.challenge_response_authentication == 1) {
				char *challenge = get_challenge(authctxt);
				if (challenge != NULL) {
					debug("sending challenge '%s'", challenge);
					packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
					packet_put_cstring(challenge);
					xfree(challenge);
					packet_send();
					packet_write_wait();
					continue;
				}
			}
			break;
		case SSH_CMSG_AUTH_TIS_RESPONSE:
			debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
			if (options.challenge_response_authentication == 1) {
				char *response = packet_get_string(&dlen);
				packet_check_eom();
				authenticated = verify_response(authctxt, response);
				memset(response, 'r', dlen);
				xfree(response);
			}
			break;

		default:
			/*
			 * Any unknown messages will be ignored (and failure
			 * returned) during authentication.
			 */
			log("Unknown message during authentication: type %d", type);
			break;
		}
#ifdef BSD_AUTH
		if (authctxt->as) {
			auth_close(authctxt->as);
			authctxt->as = NULL;
		}
#endif
		if (!authctxt->valid && authenticated)
			fatal("INTERNAL ERROR: authenticated invalid user %s",
			    authctxt->user);

#ifdef _UNICOS
		if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated)
			cray_login_failure(authctxt->user, IA_UDBERR);
		if (authenticated && cray_access_denied(authctxt->user)) {
			authenticated = 0;
			fatal("Access denied for user %s.",authctxt->user);
		}
#endif /* _UNICOS */

#ifdef HAVE_CYGWIN
		if (authenticated &&
		    !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) {
			packet_disconnect("Authentication rejected for uid %d.",
			pw == NULL ? -1 : pw->pw_uid);
			authenticated = 0;
		}
#else
		/* Special handling for root */
		if (authenticated && authctxt->pw->pw_uid == 0 &&
		    !auth_root_allowed(get_authname(type)))
			authenticated = 0;
#endif
#ifdef USE_PAM
		if (!use_privsep && authenticated && 
		    !do_pam_account(pw->pw_name, client_user))
			authenticated = 0;
#endif

		/* Log before sending the reply */
		auth_log(authctxt, authenticated, get_authname(type), info);

		if (client_user != NULL) {
			xfree(client_user);
			client_user = NULL;
		}

		if (authenticated)
			return;

		if (authctxt->failures++ > AUTH_FAIL_MAX) {
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
		}

		packet_start(SSH_SMSG_FAILURE);
		packet_send();
		packet_write_wait();
	}
}
コード例 #3
0
ファイル: ssh-rsa.c プロジェクト: msftguy/openssh-sc
int
ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	Buffer b;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	char *ktype;
	u_char *sigblob;
	u_int len, modlen;
#ifdef USE_LEGACY_RSA_VERIFY
	u_char digest[EVP_MAX_MD_SIZE];
	u_int dlen;
#endif
	int rlen, ret, nid;

	if (key == NULL || key->rsa == NULL || (key->type != KEY_RSA &&
	    key->type != KEY_RSA_CERT && key->type != KEY_RSA_CERT_V00)) {
		error("ssh_rsa_verify: no RSA key");
		return -1;
	}
	if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
		error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
		    BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
		return -1;
	}
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_cstring(&b, NULL);
	if (strcmp("ssh-rsa", ktype) != 0) {
		error("ssh_rsa_verify: cannot handle type %s", ktype);
		buffer_free(&b);
		xfree(ktype);
		return -1;
	}
	xfree(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
		xfree(sigblob);
		return -1;
	}
	/* RSA_verify expects a signature of RSA_size */
	modlen = RSA_size(key->rsa);
	if (len > modlen) {
		error("ssh_rsa_verify: len %u > modlen %u", len, modlen);
		xfree(sigblob);
		return -1;
	} else if (len < modlen) {
		u_int diff = modlen - len;
		debug("ssh_rsa_verify: add padding: modlen %u > len %u",
		    modlen, len);
		sigblob = xrealloc(sigblob, 1, modlen);
		memmove(sigblob + diff, sigblob, len);
		memset(sigblob, 0, diff);
		len = modlen;
	}
	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
		xfree(sigblob);
		return -1;
	}

#ifdef USE_LEGACY_RSA_VERIFY
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
	memset(digest, 'd', sizeof(digest));
#else /*ndef USE_LEGACY_RSA_VERIFY*/
{
	EVP_PKEY *pkey;

	ret = -1;
	pkey = EVP_PKEY_new();
	if (pkey == NULL) {
		error("%s: out of memory", __func__);
		goto done;
	}

	EVP_PKEY_set1_RSA(pkey, key->rsa);

	ssh_EVP_MD_CTX_init(&md);

	ret = ssh_EVP_VerifyInit(&md, evp_md);
	if (ret <= 0) {
		char ebuf[256];
		error("%s: EVP_VerifyInit fail with errormsg='%.*s'"
		, __func__
		, (int)sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)));
		goto clean;
	}

	ret = ssh_EVP_VerifyUpdate(&md, data, datalen);
	if (ret <= 0) {
		char ebuf[256];
		error("%s: EVP_VerifyUpdate fail with errormsg='%.*s'"
		, __func__
		, (int)sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)));
		goto clean;
	}

	ret = EVP_VerifyFinal(&md, sigblob, len, pkey);
	if (ret <= 0) {
		char ebuf[256];
		error("%s: EVP_VerifyFinal fail with errormsg='%.*s'"
		, __func__
		, (int)sizeof(ebuf), openssl_errormsg(ebuf, sizeof(ebuf)));
		goto clean;
	}

clean:
	ssh_EVP_MD_CTX_cleanup(&md);

done:
	if (pkey != NULL) EVP_PKEY_free(pkey);
}
#endif /*ndef USE_LEGACY_RSA_VERIFY*/

	memset(sigblob, 's', len);
	xfree(sigblob);
	debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
	return ret;
}
コード例 #4
0
ファイル: rsa_impl.c プロジェクト: aaapei/libquic
int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                        const uint8_t *in, size_t in_len, int padding) {
  const unsigned rsa_size = RSA_size(rsa);
  BIGNUM *f, *result;
  uint8_t *buf = NULL;
  BN_CTX *ctx = NULL;
  int i, ret = 0;

  if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
    return 0;
  }

  if (max_out < rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
    return 0;
  }

  if (BN_ucmp(rsa->n, rsa->e) <= 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
    return 0;
  }

  /* for large moduli, enforce exponent limit */
  if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
      BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
    return 0;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }

  BN_CTX_start(ctx);
  f = BN_CTX_get(ctx);
  result = BN_CTX_get(ctx);
  buf = OPENSSL_malloc(rsa_size);
  if (!f || !result || !buf) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  switch (padding) {
    case RSA_PKCS1_PADDING:
      i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len);
      break;
    case RSA_PKCS1_OAEP_PADDING:
      /* Use the default parameters: SHA-1 for both hashes and no label. */
      i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len,
                                          NULL, 0, NULL, NULL);
      break;
    case RSA_NO_PADDING:
      i = RSA_padding_add_none(buf, rsa_size, in, in_len);
      break;
    default:
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
      goto err;
  }

  if (i <= 0) {
    goto err;
  }

  if (BN_bin2bn(buf, rsa_size, f) == NULL) {
    goto err;
  }

  if (BN_ucmp(f, rsa->n) >= 0) {
    /* usually the padding functions would catch this */
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
    goto err;
  }

  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
      goto err;
    }
  }

  if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
    goto err;
  }

  /* put in leading 0 bytes if the number is less than the length of the
   * modulus */
  if (!BN_bn2bin_padded(out, rsa_size, result)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  *out_len = rsa_size;
  ret = 1;

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  if (buf != NULL) {
    OPENSSL_cleanse(buf, rsa_size);
    OPENSSL_free(buf);
  }

  return ret;
}
コード例 #5
0
ファイル: prime.c プロジェクト: AxiomaAbsurdo/time_web_app
int BN_enhanced_miller_rabin_primality_test(
    enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations,
    BN_CTX *ctx, BN_GENCB *cb) {
  // Enhanced Miller-Rabin is only valid on odd integers greater than 3.
  if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT);
    return 0;
  }

  if (iterations == BN_prime_checks) {
    iterations = BN_prime_checks_for_size(BN_num_bits(w));
  }

  int ret = 0;
  BN_MONT_CTX *mont = NULL;

  BN_CTX_start(ctx);

  BIGNUM *w1 = BN_CTX_get(ctx);
  if (w1 == NULL ||
      !BN_copy(w1, w) ||
      !BN_sub_word(w1, 1)) {
    goto err;
  }

  // Write w1 as m*2^a (Steps 1 and 2).
  int a = 0;
  while (!BN_is_bit_set(w1, a)) {
    a++;
  }
  BIGNUM *m = BN_CTX_get(ctx);
  if (m == NULL ||
      !BN_rshift(m, w1, a)) {
    goto err;
  }

  BIGNUM *b = BN_CTX_get(ctx);
  BIGNUM *g = BN_CTX_get(ctx);
  BIGNUM *z = BN_CTX_get(ctx);
  BIGNUM *x = BN_CTX_get(ctx);
  BIGNUM *x1 = BN_CTX_get(ctx);
  if (b == NULL ||
      g == NULL ||
      z == NULL ||
      x == NULL ||
      x1 == NULL) {
    goto err;
  }

  // Montgomery setup for computations mod A
  mont = BN_MONT_CTX_new();
  if (mont == NULL ||
      !BN_MONT_CTX_set(mont, w, ctx)) {
    goto err;
  }

  // The following loop performs in inner iteration of the Enhanced Miller-Rabin
  // Primality test (Step 4).
  for (int i = 1; i <= iterations; i++) {
    // Step 4.1-4.2
    if (!BN_rand_range_ex(b, 2, w1)) {
      goto err;
    }

    // Step 4.3-4.4
    if (!BN_gcd(g, b, w, ctx)) {
      goto err;
    }
    if (BN_cmp_word(g, 1) > 0) {
      *out_result = bn_composite;
      ret = 1;
      goto err;
    }

    // Step 4.5
    if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) {
      goto err;
    }

    // Step 4.6
    if (BN_is_one(z) || BN_cmp(z, w1) == 0) {
      goto loop;
    }

    // Step 4.7
    for (int j = 1; j < a; j++) {
      if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) {
        goto err;
      }
      if (BN_cmp(z, w1) == 0) {
        goto loop;
      }
      if (BN_is_one(z)) {
        goto composite;
      }
    }

    // Step 4.8-4.9
    if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) {
      goto err;
    }

    // Step 4.10-4.11
    if (!BN_is_one(z) && !BN_copy(x, z)) {
      goto err;
    }

 composite:
    // Step 4.12-4.14
    if (!BN_copy(x1, x) ||
        !BN_sub_word(x1, 1) ||
        !BN_gcd(g, x1, w, ctx)) {
      goto err;
    }
    if (BN_cmp_word(g, 1) > 0) {
      *out_result = bn_composite;
    } else {
      *out_result = bn_non_prime_power_composite;
    }

    ret = 1;
    goto err;

 loop:
    // Step 4.15
    if (!BN_GENCB_call(cb, 1, i)) {
      goto err;
    }
  }

  *out_result = bn_probably_prime;
  ret = 1;

err:
  BN_MONT_CTX_free(mont);
  BN_CTX_end(ctx);

  return ret;
}
コード例 #6
0
ファイル: dh.c プロジェクト: antonyantony/openssh
static int
parse_prime(int linenum, char *line, struct dhgroup *dhg)
{
	char *cp, *arg;
	char *strsize, *gen, *prime;
	const char *errstr = NULL;
	long long n;

	dhg->p = dhg->g = NULL;
	cp = line;
	if ((arg = strdelim(&cp)) == NULL)
		return 0;
	/* Ignore leading whitespace */
	if (*arg == '\0')
		arg = strdelim(&cp);
	if (!arg || !*arg || *arg == '#')
		return 0;

	/* time */
	if (cp == NULL || *arg == '\0')
		goto truncated;
	arg = strsep(&cp, " "); /* type */
	if (cp == NULL || *arg == '\0')
		goto truncated;
	/* Ensure this is a safe prime */
	n = strtonum(arg, 0, 5, &errstr);
	if (errstr != NULL || n != MODULI_TYPE_SAFE) {
		error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE);
		goto fail;
	}
	arg = strsep(&cp, " "); /* tests */
	if (cp == NULL || *arg == '\0')
		goto truncated;
	/* Ensure prime has been tested and is not composite */
	n = strtonum(arg, 0, 0x1f, &errstr);
	if (errstr != NULL ||
	    (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) {
		error("moduli:%d: invalid moduli tests flag", linenum);
		goto fail;
	}
	arg = strsep(&cp, " "); /* tries */
	if (cp == NULL || *arg == '\0')
		goto truncated;
	n = strtonum(arg, 0, 1<<30, &errstr);
	if (errstr != NULL || n == 0) {
		error("moduli:%d: invalid primality trial count", linenum);
		goto fail;
	}
	strsize = strsep(&cp, " "); /* size */
	if (cp == NULL || *strsize == '\0' ||
	    (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
	    errstr) {
		error("moduli:%d: invalid prime length", linenum);
		goto fail;
	}
	/* The whole group is one bit larger */
	dhg->size++;
	gen = strsep(&cp, " "); /* gen */
	if (cp == NULL || *gen == '\0')
		goto truncated;
	prime = strsep(&cp, " "); /* prime */
	if (cp != NULL || *prime == '\0') {
 truncated:
		error("moduli:%d: truncated", linenum);
		goto fail;
	}

	if ((dhg->g = BN_new()) == NULL ||
	    (dhg->p = BN_new()) == NULL) {
		error("parse_prime: BN_new failed");
		goto fail;
	}
	if (BN_hex2bn(&dhg->g, gen) == 0) {
		error("moduli:%d: could not parse generator value", linenum);
		goto fail;
	}
	if (BN_hex2bn(&dhg->p, prime) == 0) {
		error("moduli:%d: could not parse prime value", linenum);
		goto fail;
	}
	if (BN_num_bits(dhg->p) != dhg->size) {
		error("moduli:%d: prime has wrong size: actual %d listed %d",
		    linenum, BN_num_bits(dhg->p), dhg->size - 1);
		goto fail;
	}
	if (BN_cmp(dhg->g, BN_value_one()) <= 0) {
		error("moduli:%d: generator is invalid", linenum);
		goto fail;
	}
	return 1;

 fail:
	BN_clear_free(dhg->g);
	BN_clear_free(dhg->p);
	dhg->g = dhg->p = NULL;
	return 0;
}
コード例 #7
0
ファイル: bn_mont.c プロジェクト: Heratom/Firefly-project
int
BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
	int ret = 0;
	BIGNUM *Ri, *R;

	BN_CTX_start(ctx);
	if ((Ri = BN_CTX_get(ctx)) == NULL)
		goto err;
	R = &(mont->RR);				/* grab RR as a temp */
	if (!BN_copy(&(mont->N), mod))
		 goto err;				/* Set N */
	mont->N.neg = 0;

#ifdef MONT_WORD
	{
		BIGNUM tmod;
		BN_ULONG buf[2];

		BN_init(&tmod);
		tmod.d = buf;
		tmod.dmax = 2;
		tmod.neg = 0;

		mont->ri = (BN_num_bits(mod) +
		    (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;

#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
		/* Only certain BN_BITS2<=32 platforms actually make use of
		 * n0[1], and we could use the #else case (with a shorter R
		 * value) for the others.  However, currently only the assembler
		 * files do know which is which. */

		BN_zero(R);
		if (!(BN_set_bit(R, 2 * BN_BITS2)))
			goto err;

		tmod.top = 0;
		if ((buf[0] = mod->d[0]))
			tmod.top = 1;
		if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
			tmod.top = 2;

		if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
			goto err; /* R*Ri */
		if (!BN_is_zero(Ri)) {
			if (!BN_sub_word(Ri, 1))
				goto err;
		}
		else /* if N mod word size == 1 */
		{
			if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
				goto err;
			/* Ri-- (mod double word size) */
			Ri->neg = 0;
			Ri->d[0] = BN_MASK2;
			Ri->d[1] = BN_MASK2;
			Ri->top = 2;
		}
		if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
			goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only couple of least significant words: */
		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
#else
		BN_zero(R);
		if (!(BN_set_bit(R, BN_BITS2)))
			goto err;	/* R */

		buf[0] = mod->d[0]; /* tmod = N mod word size */
		buf[1] = 0;
		tmod.top = buf[0] != 0 ? 1 : 0;
		/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, BN_BITS2))
			goto err; /* R*Ri */
		if (!BN_is_zero(Ri)) {
			if (!BN_sub_word(Ri, 1))
				goto err;
		}
		else /* if N mod word size == 1 */
		{
			if (!BN_set_word(Ri, BN_MASK2))
				goto err;  /* Ri-- (mod word size) */
		}
		if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
			goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only least significant word: */
		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
		mont->n0[1] = 0;
#endif
	}
#else /* !MONT_WORD */
	{ /* bignum version */
		mont->ri = BN_num_bits(&mont->N);
		BN_zero(R);
		if (!BN_set_bit(R, mont->ri))
			goto err;  /* R = 2^ri */
		/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, mont->ri))
			goto err; /* R*Ri */
		if (!BN_sub_word(Ri, 1))
			goto err;
		/* Ni = (R*Ri-1) / N */
		if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx))
			goto err;
	}
#endif

	/* setup RR for conversions */
	BN_zero(&(mont->RR));
	if (!BN_set_bit(&(mont->RR), mont->ri*2))
		goto err;
	if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
		goto err;

	ret = 1;

err:
	BN_CTX_end(ctx);
	return ret;
}
コード例 #8
0
ファイル: dsa_ameth.c プロジェクト: SpongeEdmund/openssl
static int dsa_bits(const EVP_PKEY *pkey)
{
    return BN_num_bits(pkey->pkey.dsa->p);
}
コード例 #9
0
ファイル: dsa_ameth.c プロジェクト: SpongeEdmund/openssl
static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
{
    unsigned char *m = NULL;
    int ret = 0;
    size_t buf_len = 0;
    const char *ktype = NULL;

    const BIGNUM *priv_key, *pub_key;

    if (ptype == 2)
        priv_key = x->priv_key;
    else
        priv_key = NULL;

    if (ptype > 0)
        pub_key = x->pub_key;
    else
        pub_key = NULL;

    if (ptype == 2)
        ktype = "Private-Key";
    else if (ptype == 1)
        ktype = "Public-Key";
    else
        ktype = "DSA-Parameters";

    update_buflen(x->p, &buf_len);
    update_buflen(x->q, &buf_len);
    update_buflen(x->g, &buf_len);
    update_buflen(priv_key, &buf_len);
    update_buflen(pub_key, &buf_len);

    m = OPENSSL_malloc(buf_len + 10);
    if (m == NULL) {
        DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (priv_key) {
        if (!BIO_indent(bp, off, 128))
            goto err;
        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
            <= 0)
            goto err;
    }

    if (!ASN1_bn_print(bp, "priv:", priv_key, m, off))
        goto err;
    if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off))
        goto err;
    if (!ASN1_bn_print(bp, "P:   ", x->p, m, off))
        goto err;
    if (!ASN1_bn_print(bp, "Q:   ", x->q, m, off))
        goto err;
    if (!ASN1_bn_print(bp, "G:   ", x->g, m, off))
        goto err;
    ret = 1;
 err:
    OPENSSL_free(m);
    return (ret);
}
コード例 #10
0
static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
		  DSA *dsa)
	{
	BN_CTX *ctx;
	BIGNUM u1,u2,t1;
	BN_MONT_CTX *mont=NULL;
	int ret = -1;
	if (!dsa->p || !dsa->q || !dsa->g)
		{
		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
		return -1;
		}

	if (BN_num_bits(dsa->q) != 160)
		{
		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
		return -1;
		}

	if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
		{
		DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
		return -1;
		}

	BN_init(&u1);
	BN_init(&u2);
	BN_init(&t1);

	if ((ctx=BN_CTX_new()) == NULL) goto err;

	if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
	    BN_ucmp(sig->r, dsa->q) >= 0)
		{
		ret = 0;
		goto err;
		}
	if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
	    BN_ucmp(sig->s, dsa->q) >= 0)
		{
		ret = 0;
		goto err;
		}

	/* Calculate W = inv(S) mod Q
	 * save W in u2 */
	if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;

	/* save M in u1 */
	if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;

	/* u1 = M * w mod q */
	if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;

	/* u2 = r * w mod q */
	if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;


	if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
		{
		mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
					CRYPTO_LOCK_DSA, dsa->p, ctx);
		if (!mont)
			goto err;
		}


	DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);
	/* BN_copy(&u1,&t1); */
	/* let u1 = u1 mod q */
	if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;

	/* V is now in u1.  If the signature is correct, it will be
	 * equal to R. */
	ret=(BN_ucmp(&u1, sig->r) == 0);

	err:
	/* XXX: surely this is wrong - if ret is 0, it just didn't verify;
	   there is no error in BN. Test should be ret == -1 (Ben) */
	if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_free(&u1);
	BN_free(&u2);
	BN_free(&t1);
	return(ret);
	}
コード例 #11
0
ファイル: ecp_smpl.c プロジェクト: Heratom/Firefly-project
int 
ec_GFp_simple_group_get_degree(const EC_GROUP * group)
{
	return BN_num_bits(&group->field);
}
コード例 #12
0
static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
	{
	BN_CTX *ctx;
	BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
	int ret=0;

	if (!dsa->p || !dsa->q || !dsa->g)
		{
		DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
		return 0;
		}

	BN_init(&k);
	BN_init(&kq);

	if (ctx_in == NULL)
		{
		if ((ctx=BN_CTX_new()) == NULL) goto err;
		}
	else
		ctx=ctx_in;

	if ((r=BN_new()) == NULL) goto err;

	/* Get random k */
	do
		if (!BN_rand_range(&k, dsa->q)) goto err;
	while (BN_is_zero(&k));
	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
		{
		BN_set_flags(&k, BN_FLG_CONSTTIME);
		}

	if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
		{
		if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
						CRYPTO_LOCK_DSA,
						dsa->p, ctx))
			goto err;
		}

	/* Compute r = (g^k mod p) mod q */

	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
		{
		if (!BN_copy(&kq, &k)) goto err;

		/* We do not want timing information to leak the length of k,
		 * so we compute g^k using an equivalent exponent of fixed length.
		 *
		 * (This is a kludge that we need because the BN_mod_exp_mont()
		 * does not let us specify the desired timing behaviour.) */

		if (!BN_add(&kq, &kq, dsa->q)) goto err;
		if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
			{
			if (!BN_add(&kq, &kq, dsa->q)) goto err;
			}

		K = &kq;
		}
	else
		{
		K = &k;
		}
	DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
			dsa->method_mont_p);
	if (!BN_mod(r,r,dsa->q,ctx)) goto err;

	/* Compute  part of 's = inv(k) (m + xr) mod q' */
	if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;

	if (*kinvp != NULL) BN_clear_free(*kinvp);
	*kinvp=kinv;
	kinv=NULL;
	if (*rp != NULL) BN_clear_free(*rp);
	*rp=r;
	ret=1;
err:
	if (!ret)
		{
		DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
		if (kinv != NULL) BN_clear_free(kinv);
		if (r != NULL) BN_clear_free(r);
		}
	if (ctx_in == NULL) BN_CTX_free(ctx);
	if (kinv != NULL) BN_clear_free(kinv);
	BN_clear_free(&k);
	BN_clear_free(&kq);
	return(ret);
	}
コード例 #13
0
ファイル: auth1.c プロジェクト: OpenDarwin-CVS/SEDarwin
/*
 * read packets, try to authenticate the user and
 * return only if authentication is successful
 */
static void
do_authloop(Authctxt *authctxt)
{
	int authenticated = 0;
	u_int bits;
	Key *client_host_key;
	BIGNUM *n;
	char *client_user, *password;
	char info[1024];
	u_int dlen;
	u_int ulen;
	int prev, type = 0;
	struct passwd *pw = authctxt->pw;

	debug("Attempting authentication for %s%.100s.",
	    authctxt->valid ? "" : "illegal user ", authctxt->user);

	/* If the user has no password, accept authentication immediately. */
	if (options.password_authentication &&
#ifdef KRB5
	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif
	    PRIVSEP(auth_password(authctxt, ""))) {
		auth_log(authctxt, 1, "without authentication", "");
		return;
	}

	/* Indicate that authentication is needed. */
	packet_start(SSH_SMSG_FAILURE);
	packet_send();
	packet_write_wait();

	client_user = NULL;

	for (;;) {
		/* default to fail */
		authenticated = 0;

		info[0] = '\0';

		/* Get a packet from the client. */
		prev = type;
		type = packet_read();

		/*
		 * If we started challenge-response authentication but the
		 * next packet is not a response to our challenge, release
		 * the resources allocated by get_challenge() (which would
		 * normally have been released by verify_response() had we
		 * received such a response)
		 */
		if (prev == SSH_CMSG_AUTH_TIS &&
		    type != SSH_CMSG_AUTH_TIS_RESPONSE)
			abandon_challenge_response(authctxt);

		/* Process the packet. */
		switch (type) {
		case SSH_CMSG_AUTH_RHOSTS_RSA:
			if (!options.rhosts_rsa_authentication) {
				verbose("Rhosts with RSA authentication disabled.");
				break;
			}
			/*
			 * Get client user name.  Note that we just have to
			 * trust the client; root on the client machine can
			 * claim to be any user.
			 */
			client_user = packet_get_string(&ulen);

			/* Get the client host key. */
			client_host_key = key_new(KEY_RSA1);
			bits = packet_get_int();
			packet_get_bignum(client_host_key->rsa->e);
			packet_get_bignum(client_host_key->rsa->n);

			if (bits != BN_num_bits(client_host_key->rsa->n))
				verbose("Warning: keysize mismatch for client_host_key: "
				    "actual %d, announced %d",
				    BN_num_bits(client_host_key->rsa->n), bits);
			packet_check_eom();

			authenticated = auth_rhosts_rsa(authctxt, client_user,
			    client_host_key);
			key_free(client_host_key);

			snprintf(info, sizeof info, " ruser %.100s", client_user);
			break;

		case SSH_CMSG_AUTH_RSA:
			if (!options.rsa_authentication) {
				verbose("RSA authentication disabled.");
				break;
			}
			/* RSA authentication requested. */
			if ((n = BN_new()) == NULL)
				fatal("do_authloop: BN_new failed");
			packet_get_bignum(n);
			packet_check_eom();
			authenticated = auth_rsa(authctxt, n);
			BN_clear_free(n);
			break;

		case SSH_CMSG_AUTH_PASSWORD:
			if (!options.password_authentication) {
				verbose("Password authentication disabled.");
				break;
			}
			/*
			 * Read user password.  It is in plain text, but was
			 * transmitted over the encrypted channel so it is
			 * not visible to an outside observer.
			 */
			password = packet_get_string(&dlen);
			packet_check_eom();

			/* Try authentication with the password. */
			authenticated = PRIVSEP(auth_password(authctxt, password));

			memset(password, 0, strlen(password));
			xfree(password);
			break;

		case SSH_CMSG_AUTH_TIS:
			debug("rcvd SSH_CMSG_AUTH_TIS");
			if (options.challenge_response_authentication == 1) {
				char *challenge = get_challenge(authctxt);
				if (challenge != NULL) {
					debug("sending challenge '%s'", challenge);
					packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
					packet_put_cstring(challenge);
					xfree(challenge);
					packet_send();
					packet_write_wait();
					continue;
				}
			}
			break;
		case SSH_CMSG_AUTH_TIS_RESPONSE:
			debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
			if (options.challenge_response_authentication == 1) {
				char *response = packet_get_string(&dlen);
				packet_check_eom();
				authenticated = verify_response(authctxt, response);
				memset(response, 'r', dlen);
				xfree(response);
			}
			break;

		default:
			/*
			 * Any unknown messages will be ignored (and failure
			 * returned) during authentication.
			 */
			logit("Unknown message during authentication: type %d", type);
			break;
		}
#ifdef BSD_AUTH
		if (authctxt->as) {
			auth_close(authctxt->as);
			authctxt->as = NULL;
		}
#endif
		if (!authctxt->valid && authenticated)
			fatal("INTERNAL ERROR: authenticated invalid user %s",
			    authctxt->user);

#ifdef _UNICOS
		if (authenticated && cray_access_denied(authctxt->user)) {
			authenticated = 0;
			fatal("Access denied for user %s.",authctxt->user);
		}
#endif /* _UNICOS */

#ifdef HAVE_CYGWIN
		if (authenticated &&
		    !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) {
			packet_disconnect("Authentication rejected for uid %d.",
			    pw == NULL ? -1 : pw->pw_uid);
			authenticated = 0;
		}
#else
		/* Special handling for root */
		if (authenticated && authctxt->pw->pw_uid == 0 &&
		    !auth_root_allowed(get_authname(type))) {
			authenticated = 0;
#if defined(HAVE_BSM_AUDIT_H) && defined(HAVE_LIBBSM)
			PRIVSEP(solaris_audit_not_console());
#endif /* BSM */
		}
#endif

#ifdef USE_PAM
		if (options.use_pam && authenticated &&
		    !PRIVSEP(do_pam_account()))
			authenticated = 0;
#endif

		/* Log before sending the reply */
		auth_log(authctxt, authenticated, get_authname(type), info);

		if (client_user != NULL) {
			xfree(client_user);
			client_user = NULL;
		}

		if (authenticated)
			return;

		if (authctxt->failures++ > AUTH_FAIL_MAX) {
#if defined(HAVE_BSM_AUDIT_H) && defined(HAVE_LIBBSM)
			PRIVSEP(solaris_audit_maxtrys());
#endif /* BSM */
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
		}
#if defined(HAVE_BSM_AUDIT_H) && defined(HAVE_LIBBSM)
		PRIVSEP(solaris_audit_bad_pw("authorization"));
#endif /* BSM */

		packet_start(SSH_SMSG_FAILURE);
		packet_send();
		packet_write_wait();
	}
}
コード例 #14
0
ファイル: bn_sqrt.c プロジェクト: prestocore/browser
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 
/* Returns 'ret' such that
 *      ret^2 == a (mod p),
 * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
 * in Algebraic Computational Number Theory", algorithm 1.5.1).
 * 'p' must be prime!
 */
	{
	BIGNUM *ret = in;
	int err = 1;
	int r;
	BIGNUM *A, *b, *q, *t, *x, *y;
	int e, i, j;
	
	if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
		{
		if (BN_abs_is_word(p, 2))
			{
			if (ret == NULL)
				ret = BN_new();
			if (ret == NULL)
				goto end;
			if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
				{
				BN_free(ret);
				return NULL;
				}
			bn_check_top(ret);
			return ret;
			}

		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
		return(NULL);
		}

	if (BN_is_zero(a) || BN_is_one(a))
		{
		if (ret == NULL)
			ret = BN_new();
		if (ret == NULL)
			goto end;
		if (!BN_set_word(ret, BN_is_one(a)))
			{
			BN_free(ret);
			return NULL;
			}
		bn_check_top(ret);
		return ret;
		}

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	b = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	t = BN_CTX_get(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	if (y == NULL) goto end;
	
	if (ret == NULL)
		ret = BN_new();
	if (ret == NULL) goto end;

	/* A = a mod p */
	if (!BN_nnmod(A, a, p, ctx)) goto end;

	/* now write  |p| - 1  as  2^e*q  where  q  is odd */
	e = 1;
	while (!BN_is_bit_set(p, e))
		e++;
	/* we'll set  q  later (if needed) */

	if (e == 1)
		{
		/* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
		 * modulo  (|p|-1)/2,  and square roots can be computed
		 * directly by modular exponentiation.
		 * We have
		 *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
		 * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
		 */
		if (!BN_rshift(q, p, 2)) goto end;
		q->neg = 0;
		if (!BN_add_word(q, 1)) goto end;
		if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
		err = 0;
		goto vrfy;
		}
	
	if (e == 2)
		{
		/* |p| == 5  (mod 8)
		 *
		 * In this case  2  is always a non-square since
		 * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
		 * So if  a  really is a square, then  2*a  is a non-square.
		 * Thus for
		 *      b := (2*a)^((|p|-5)/8),
		 *      i := (2*a)*b^2
		 * we have
		 *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
		 *         = (2*a)^((p-1)/2)
		 *         = -1;
		 * so if we set
		 *      x := a*b*(i-1),
		 * then
		 *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
		 *         = a^2 * b^2 * (-2*i)
		 *         = a*(-i)*(2*a*b^2)
		 *         = a*(-i)*i
		 *         = a.
		 *
		 * (This is due to A.O.L. Atkin, 
		 * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
		 * November 1992.)
		 */

		/* t := 2*a */
		if (!BN_mod_lshift1_quick(t, A, p)) goto end;

		/* b := (2*a)^((|p|-5)/8) */
		if (!BN_rshift(q, p, 3)) goto end;
		q->neg = 0;
		if (!BN_mod_exp(b, t, q, p, ctx)) goto end;

		/* y := b^2 */
		if (!BN_mod_sqr(y, b, p, ctx)) goto end;

		/* t := (2*a)*b^2 - 1*/
		if (!BN_mod_mul(t, t, y, p, ctx)) goto end;
		if (!BN_sub_word(t, 1)) goto end;

		/* x = a*b*t */
		if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;

		if (!BN_copy(ret, x)) goto end;
		err = 0;
		goto vrfy;
		}
	
	/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
	 * First, find some  y  that is not a square. */
	if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
	q->neg = 0;
	i = 2;
	do
		{
		/* For efficiency, try small numbers first;
		 * if this fails, try random numbers.
		 */
		if (i < 22)
			{
			if (!BN_set_word(y, i)) goto end;
			}
		else
			{
			if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end;
			if (BN_ucmp(y, p) >= 0)
				{
				if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end;
				}
			/* now 0 <= y < |p| */
			if (BN_is_zero(y))
				if (!BN_set_word(y, i)) goto end;
			}
		
		r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
		if (r < -1) goto end;
		if (r == 0)
			{
			/* m divides p */
			BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
			goto end;
			}
		}
	while (r == 1 && ++i < 82);
	
	if (r != -1)
		{
		/* Many rounds and still no non-square -- this is more likely
		 * a bug than just bad luck.
		 * Even if  p  is not prime, we should have found some  y
		 * such that r == -1.
		 */
		BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
		goto end;
		}

	/* Here's our actual 'q': */
	if (!BN_rshift(q, q, e)) goto end;

	/* Now that we have some non-square, we can find an element
	 * of order  2^e  by computing its q'th power. */
	if (!BN_mod_exp(y, y, q, p, ctx)) goto end;
	if (BN_is_one(y))
		{
		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
		goto end;
		}

	/* Now we know that (if  p  is indeed prime) there is an integer
	 * k,  0 <= k < 2^e,  such that
	 *
	 *      a^q * y^k == 1   (mod p).
	 *
	 * As  a^q  is a square and  y  is not,  k  must be even.
	 * q+1  is even, too, so there is an element
	 *
	 *     X := a^((q+1)/2) * y^(k/2),
	 *
	 * and it satisfies
	 *
	 *     X^2 = a^q * a     * y^k
	 *         = a,
	 *
	 * so it is the square root that we are looking for.
	 */
	
	/* t := (q-1)/2  (note that  q  is odd) */
	if (!BN_rshift1(t, q)) goto end;
	
	/* x := a^((q-1)/2) */
	if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
		{
		if (!BN_nnmod(t, A, p, ctx)) goto end;
		if (BN_is_zero(t))
			{
			/* special case: a == 0  (mod p) */
			BN_zero(ret);
			err = 0;
			goto end;
			}
		else
			if (!BN_one(x)) goto end;
		}
	else
		{
		if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
		if (BN_is_zero(x))
			{
			/* special case: a == 0  (mod p) */
			BN_zero(ret);
			err = 0;
			goto end;
			}
		}

	/* b := a*x^2  (= a^q) */
	if (!BN_mod_sqr(b, x, p, ctx)) goto end;
	if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
	
	/* x := a*x    (= a^((q+1)/2)) */
	if (!BN_mod_mul(x, x, A, p, ctx)) goto end;

	while (1)
		{
		/* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
		 * where  E  refers to the original value of  e,  which we
		 * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
		 *
		 * We have  a*b = x^2,
		 *    y^2^(e-1) = -1,
		 *    b^2^(e-1) = 1.
		 */

		if (BN_is_one(b))
			{
			if (!BN_copy(ret, x)) goto end;
			err = 0;
			goto vrfy;
			}


		/* find smallest  i  such that  b^(2^i) = 1 */
		i = 1;
		if (!BN_mod_sqr(t, b, p, ctx)) goto end;
		while (!BN_is_one(t))
			{
			i++;
			if (i == e)
				{
				BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
				goto end;
				}
			if (!BN_mod_mul(t, t, t, p, ctx)) goto end;
			}
		

		/* t := y^2^(e - i - 1) */
		if (!BN_copy(t, y)) goto end;
		for (j = e - i - 1; j > 0; j--)
			{
			if (!BN_mod_sqr(t, t, p, ctx)) goto end;
			}
		if (!BN_mod_mul(y, t, t, p, ctx)) goto end;
		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
		if (!BN_mod_mul(b, b, y, p, ctx)) goto end;
		e = i;
		}

 vrfy:
	if (!err)
		{
		/* verify the result -- the input might have been not a square
		 * (test added in 0.9.8) */
		
		if (!BN_mod_sqr(x, ret, p, ctx))
			err = 1;
		
		if (!err && 0 != BN_cmp(x, A))
			{
			BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
			err = 1;
			}
		}

 end:
	if (err)
		{
		if (ret != NULL && ret != in)
			{
			BN_clear_free(ret);
			}
		ret = NULL;
		}
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return ret;
	}
コード例 #15
0
ファイル: sqrt.c プロジェクト: AxiomaAbsurdo/time_web_app
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
  // Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm
  // (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory",
  // algorithm 1.5.1). |p| is assumed to be a prime.

  BIGNUM *ret = in;
  int err = 1;
  int r;
  BIGNUM *A, *b, *q, *t, *x, *y;
  int e, i, j;

  if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
    if (BN_abs_is_word(p, 2)) {
      if (ret == NULL) {
        ret = BN_new();
      }
      if (ret == NULL) {
        goto end;
      }
      if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
        if (ret != in) {
          BN_free(ret);
        }
        return NULL;
      }
      return ret;
    }

    OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
    return (NULL);
  }

  if (BN_is_zero(a) || BN_is_one(a)) {
    if (ret == NULL) {
      ret = BN_new();
    }
    if (ret == NULL) {
      goto end;
    }
    if (!BN_set_word(ret, BN_is_one(a))) {
      if (ret != in) {
        BN_free(ret);
      }
      return NULL;
    }
    return ret;
  }

  BN_CTX_start(ctx);
  A = BN_CTX_get(ctx);
  b = BN_CTX_get(ctx);
  q = BN_CTX_get(ctx);
  t = BN_CTX_get(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (y == NULL) {
    goto end;
  }

  if (ret == NULL) {
    ret = BN_new();
  }
  if (ret == NULL) {
    goto end;
  }

  // A = a mod p
  if (!BN_nnmod(A, a, p, ctx)) {
    goto end;
  }

  // now write  |p| - 1  as  2^e*q  where  q  is odd
  e = 1;
  while (!BN_is_bit_set(p, e)) {
    e++;
  }
  // we'll set  q  later (if needed)

  if (e == 1) {
    // The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
    // modulo  (|p|-1)/2,  and square roots can be computed
    // directly by modular exponentiation.
    // We have
    //     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
    // so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
    if (!BN_rshift(q, p, 2)) {
      goto end;
    }
    q->neg = 0;
    if (!BN_add_word(q, 1) ||
        !BN_mod_exp_mont(ret, A, q, p, ctx, NULL)) {
      goto end;
    }
    err = 0;
    goto vrfy;
  }

  if (e == 2) {
    // |p| == 5  (mod 8)
    //
    // In this case  2  is always a non-square since
    // Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
    // So if  a  really is a square, then  2*a  is a non-square.
    // Thus for
    //      b := (2*a)^((|p|-5)/8),
    //      i := (2*a)*b^2
    // we have
    //     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
    //         = (2*a)^((p-1)/2)
    //         = -1;
    // so if we set
    //      x := a*b*(i-1),
    // then
    //     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
    //         = a^2 * b^2 * (-2*i)
    //         = a*(-i)*(2*a*b^2)
    //         = a*(-i)*i
    //         = a.
    //
    // (This is due to A.O.L. Atkin,
    // <URL:
    //http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
    // November 1992.)

    // t := 2*a
    if (!BN_mod_lshift1_quick(t, A, p)) {
      goto end;
    }

    // b := (2*a)^((|p|-5)/8)
    if (!BN_rshift(q, p, 3)) {
      goto end;
    }
    q->neg = 0;
    if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) {
      goto end;
    }

    // y := b^2
    if (!BN_mod_sqr(y, b, p, ctx)) {
      goto end;
    }

    // t := (2*a)*b^2 - 1
    if (!BN_mod_mul(t, t, y, p, ctx) ||
        !BN_sub_word(t, 1)) {
      goto end;
    }

    // x = a*b*t
    if (!BN_mod_mul(x, A, b, p, ctx) ||
        !BN_mod_mul(x, x, t, p, ctx)) {
      goto end;
    }

    if (!BN_copy(ret, x)) {
      goto end;
    }
    err = 0;
    goto vrfy;
  }

  // e > 2, so we really have to use the Tonelli/Shanks algorithm.
  // First, find some  y  that is not a square.
  if (!BN_copy(q, p)) {
    goto end;  // use 'q' as temp
  }
  q->neg = 0;
  i = 2;
  do {
    // For efficiency, try small numbers first;
    // if this fails, try random numbers.
    if (i < 22) {
      if (!BN_set_word(y, i)) {
        goto end;
      }
    } else {
      if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) {
        goto end;
      }
      if (BN_ucmp(y, p) >= 0) {
        if (!(p->neg ? BN_add : BN_sub)(y, y, p)) {
          goto end;
        }
      }
      // now 0 <= y < |p|
      if (BN_is_zero(y)) {
        if (!BN_set_word(y, i)) {
          goto end;
        }
      }
    }

    r = bn_jacobi(y, q, ctx);  // here 'q' is |p|
    if (r < -1) {
      goto end;
    }
    if (r == 0) {
      // m divides p
      OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
      goto end;
    }
  } while (r == 1 && ++i < 82);

  if (r != -1) {
    // Many rounds and still no non-square -- this is more likely
    // a bug than just bad luck.
    // Even if  p  is not prime, we should have found some  y
    // such that r == -1.
    OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
    goto end;
  }

  // Here's our actual 'q':
  if (!BN_rshift(q, q, e)) {
    goto end;
  }

  // Now that we have some non-square, we can find an element
  // of order  2^e  by computing its q'th power.
  if (!BN_mod_exp_mont(y, y, q, p, ctx, NULL)) {
    goto end;
  }
  if (BN_is_one(y)) {
    OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
    goto end;
  }

  // Now we know that (if  p  is indeed prime) there is an integer
  // k,  0 <= k < 2^e,  such that
  //
  //      a^q * y^k == 1   (mod p).
  //
  // As  a^q  is a square and  y  is not,  k  must be even.
  // q+1  is even, too, so there is an element
  //
  //     X := a^((q+1)/2) * y^(k/2),
  //
  // and it satisfies
  //
  //     X^2 = a^q * a     * y^k
  //         = a,
  //
  // so it is the square root that we are looking for.

  // t := (q-1)/2  (note that  q  is odd)
  if (!BN_rshift1(t, q)) {
    goto end;
  }

  // x := a^((q-1)/2)
  if (BN_is_zero(t))  // special case: p = 2^e + 1
  {
    if (!BN_nnmod(t, A, p, ctx)) {
      goto end;
    }
    if (BN_is_zero(t)) {
      // special case: a == 0  (mod p)
      BN_zero(ret);
      err = 0;
      goto end;
    } else if (!BN_one(x)) {
      goto end;
    }
  } else {
    if (!BN_mod_exp_mont(x, A, t, p, ctx, NULL)) {
      goto end;
    }
    if (BN_is_zero(x)) {
      // special case: a == 0  (mod p)
      BN_zero(ret);
      err = 0;
      goto end;
    }
  }

  // b := a*x^2  (= a^q)
  if (!BN_mod_sqr(b, x, p, ctx) ||
      !BN_mod_mul(b, b, A, p, ctx)) {
    goto end;
  }

  // x := a*x    (= a^((q+1)/2))
  if (!BN_mod_mul(x, x, A, p, ctx)) {
    goto end;
  }

  while (1) {
    // Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
    // where  E  refers to the original value of  e,  which we
    // don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
    //
    // We have  a*b = x^2,
    //    y^2^(e-1) = -1,
    //    b^2^(e-1) = 1.

    if (BN_is_one(b)) {
      if (!BN_copy(ret, x)) {
        goto end;
      }
      err = 0;
      goto vrfy;
    }


    // find smallest  i  such that  b^(2^i) = 1
    i = 1;
    if (!BN_mod_sqr(t, b, p, ctx)) {
      goto end;
    }
    while (!BN_is_one(t)) {
      i++;
      if (i == e) {
        OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
        goto end;
      }
      if (!BN_mod_mul(t, t, t, p, ctx)) {
        goto end;
      }
    }


    // t := y^2^(e - i - 1)
    if (!BN_copy(t, y)) {
      goto end;
    }
    for (j = e - i - 1; j > 0; j--) {
      if (!BN_mod_sqr(t, t, p, ctx)) {
        goto end;
      }
    }
    if (!BN_mod_mul(y, t, t, p, ctx) ||
        !BN_mod_mul(x, x, t, p, ctx) ||
        !BN_mod_mul(b, b, y, p, ctx)) {
      goto end;
    }
    e = i;
  }

vrfy:
  if (!err) {
    // verify the result -- the input might have been not a square
    // (test added in 0.9.8)

    if (!BN_mod_sqr(x, ret, p, ctx)) {
      err = 1;
    }

    if (!err && 0 != BN_cmp(x, A)) {
      OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
      err = 1;
    }
  }

end:
  if (err) {
    if (ret != in) {
      BN_clear_free(ret);
    }
    ret = NULL;
  }
  BN_CTX_end(ctx);
  return ret;
}
コード例 #16
0
ファイル: kexdhs.c プロジェクト: ajinkya93/OpenBSD
int
input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
{
	struct ssh *ssh = ctxt;
	struct kex *kex = ssh->kex;
	BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
	struct sshkey *server_host_public, *server_host_private;
	u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
	u_char hash[SSH_DIGEST_MAX_LENGTH];
	size_t sbloblen, slen;
	size_t klen = 0, hashlen;
	int kout, r;

	if (kex->load_host_public_key == NULL ||
	    kex->load_host_private_key == NULL) {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	server_host_public = kex->load_host_public_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	server_host_private = kex->load_host_private_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	if (server_host_public == NULL) {
		r = SSH_ERR_NO_HOSTKEY_LOADED;
		goto out;
	}

	/* key, cert */
	if ((dh_client_pub = BN_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		goto out;

#ifdef DEBUG_KEXDH
	fprintf(stderr, "dh_client_pub= ");
	BN_print_fp(stderr, dh_client_pub);
	fprintf(stderr, "\n");
	debug("bits %d", BN_num_bits(dh_client_pub));
#endif

#ifdef DEBUG_KEXDH
	DHparams_print_fp(stderr, kex->dh);
	fprintf(stderr, "pub= ");
	BN_print_fp(stderr, kex->dh->pub_key);
	fprintf(stderr, "\n");
#endif
	if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
		sshpkt_disconnect(ssh, "bad client public DH value");
		r = SSH_ERR_MESSAGE_INCOMPLETE;
		goto out;
	}

	klen = DH_size(kex->dh);
	if ((kbuf = malloc(klen)) == NULL ||
	    (shared_secret = BN_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 ||
	    BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
#ifdef DEBUG_KEXDH
	dump_digest("shared secret", kbuf, kout);
#endif
	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
	    &sbloblen)) != 0)
		goto out;
	/* calc H */
	hashlen = sizeof(hash);
	if ((r = kex_dh_hash(
	    kex->client_version_string,
	    kex->server_version_string,
	    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
	    server_host_key_blob, sbloblen,
	    dh_client_pub,
	    kex->dh->pub_key,
	    shared_secret,
	    hash, &hashlen)) != 0)
		goto out;

	/* save session id := H */
	if (kex->session_id == NULL) {
		kex->session_id_len = hashlen;
		kex->session_id = malloc(kex->session_id_len);
		if (kex->session_id == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		memcpy(kex->session_id, hash, kex->session_id_len);
	}

	/* sign H */
	if ((r = kex->sign(server_host_private, server_host_public, &signature,
	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
		goto out;

	/* destroy_sensitive_data(); */

	/* send server hostkey, DH pubkey 'f' and singed H */
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
	    (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||	/* f */
	    (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;

	if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
		r = kex_send_newkeys(ssh);
 out:
	explicit_bzero(hash, sizeof(hash));
	DH_free(kex->dh);
	kex->dh = NULL;
	if (dh_client_pub)
		BN_clear_free(dh_client_pub);
	if (kbuf) {
		explicit_bzero(kbuf, klen);
		free(kbuf);
	}
	if (shared_secret)
		BN_clear_free(shared_secret);
	free(server_host_key_blob);
	free(signature);
	return r;
}
コード例 #17
0
ファイル: dsaparam.c プロジェクト: soundsrc/git-lfs-server
int
dsaparam_main(int argc, char **argv)
{
	DSA *dsa = NULL;
	int i;
	BIO *in = NULL, *out = NULL;
	int ret = 1;
	int numbits = -1;
	char *strbits = NULL;

	if (single_execution) {
		if (pledge("stdio cpath wpath rpath", NULL) == -1) {
			perror("pledge");
			exit(1);
		}
	}

	memset(&dsaparam_config, 0, sizeof(dsaparam_config));

	dsaparam_config.informat = FORMAT_PEM;
	dsaparam_config.outformat = FORMAT_PEM;

	if (options_parse(argc, argv, dsaparam_options, &strbits, NULL) != 0) {
		dsaparam_usage();
		goto end;
	}

	if (strbits != NULL) {
		const char *errstr;
		numbits = strtonum(strbits, 0, INT_MAX, &errstr);
		if (errstr) {
			fprintf(stderr, "Invalid number of bits: %s", errstr);
			goto end;
		}
	}

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if (in == NULL || out == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (dsaparam_config.infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, dsaparam_config.infile) <= 0) {
			perror(dsaparam_config.infile);
			goto end;
		}
	}
	if (dsaparam_config.outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, dsaparam_config.outfile) <= 0) {
			perror(dsaparam_config.outfile);
			goto end;
		}
	}

	if (numbits > 0) {
		BN_GENCB cb;
		BN_GENCB_set(&cb, dsa_cb, bio_err);
		dsa = DSA_new();
		if (!dsa) {
			BIO_printf(bio_err, "Error allocating DSA object\n");
			goto end;
		}
		BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", numbits);
		BIO_printf(bio_err, "This could take some time\n");
		if (!DSA_generate_parameters_ex(dsa, numbits, NULL, 0, NULL, NULL, &cb)) {
			ERR_print_errors(bio_err);
			BIO_printf(bio_err, "Error, DSA key generation failed\n");
			goto end;
		}
	} else if (dsaparam_config.informat == FORMAT_ASN1)
		dsa = d2i_DSAparams_bio(in, NULL);
	else if (dsaparam_config.informat == FORMAT_PEM)
		dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
	else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}
	if (dsa == NULL) {
		BIO_printf(bio_err, "unable to load DSA parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (dsaparam_config.text) {
		DSAparams_print(out, dsa);
	}
	if (dsaparam_config.C) {
		unsigned char *data;
		int l, len, bits_p;

		len = BN_num_bytes(dsa->p);
		bits_p = BN_num_bits(dsa->p);
		data = malloc(len + 20);
		if (data == NULL) {
			perror("malloc");
			goto end;
		}
		l = BN_bn2bin(dsa->p, data);
		printf("static unsigned char dsa%d_p[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dsa->q, data);
		printf("static unsigned char dsa%d_q[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t};\n");

		l = BN_bn2bin(dsa->g, data);
		printf("static unsigned char dsa%d_g[] = {", bits_p);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t");
			printf("0x%02X, ", data[i]);
		}
		free(data);
		printf("\n\t};\n\n");

		printf("DSA *get_dsa%d()\n\t{\n", bits_p);
		printf("\tDSA *dsa;\n\n");
		printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n");
		printf("\tdsa->p = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n",
		    bits_p, bits_p);
		printf("\tdsa->q = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n",
		    bits_p, bits_p);
		printf("\tdsa->g = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n",
		    bits_p, bits_p);
		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
		printf("\treturn(dsa);\n\t}\n");
	}
	if (!dsaparam_config.noout) {
		if (dsaparam_config.outformat == FORMAT_ASN1)
			i = i2d_DSAparams_bio(out, dsa);
		else if (dsaparam_config.outformat == FORMAT_PEM)
			i = PEM_write_bio_DSAparams(out, dsa);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write DSA parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (dsaparam_config.genkey) {
		DSA *dsakey;

		if ((dsakey = DSAparams_dup(dsa)) == NULL)
			goto end;
		if (!DSA_generate_key(dsakey)) {
			ERR_print_errors(bio_err);
			DSA_free(dsakey);
			goto end;
		}
		if (dsaparam_config.outformat == FORMAT_ASN1)
			i = i2d_DSAPrivateKey_bio(out, dsakey);
		else if (dsaparam_config.outformat == FORMAT_PEM)
			i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			DSA_free(dsakey);
			goto end;
		}
		DSA_free(dsakey);
	}
	ret = 0;

end:
	BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (dsa != NULL)
		DSA_free(dsa);

	return (ret);
}
コード例 #18
0
ファイル: kexdhc.c プロジェクト: pombredanne/freebsd
void
kexdh_client(Kex *kex)
{
    BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
    DH *dh;
    Key *server_host_key;
    u_char *server_host_key_blob = NULL, *signature = NULL;
    u_char *kbuf, *hash;
    u_int klen, slen, sbloblen, hashlen;
    int kout;

    /* generate and send 'e', client DH public key */
    switch (kex->kex_type) {
    case KEX_DH_GRP1_SHA1:
        dh = dh_new_group1();
        break;
    case KEX_DH_GRP14_SHA1:
        dh = dh_new_group14();
        break;
    default:
        fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
    }
    dh_gen_key(dh, kex->we_need * 8);
    packet_start(SSH2_MSG_KEXDH_INIT);
    packet_put_bignum2(dh->pub_key);
    packet_send();

    debug("sending SSH2_MSG_KEXDH_INIT");
#ifdef DEBUG_KEXDH
    DHparams_print_fp(stderr, dh);
    fprintf(stderr, "pub= ");
    BN_print_fp(stderr, dh->pub_key);
    fprintf(stderr, "\n");
#endif

    debug("expecting SSH2_MSG_KEXDH_REPLY");
    packet_read_expect(SSH2_MSG_KEXDH_REPLY);

    /* key, cert */
    server_host_key_blob = packet_get_string(&sbloblen);
    server_host_key = key_from_blob(server_host_key_blob, sbloblen);
    if (server_host_key == NULL)
        fatal("cannot decode server_host_key_blob");
    if (server_host_key->type != kex->hostkey_type)
        fatal("type mismatch for decoded server_host_key_blob");
    if (kex->verify_host_key == NULL)
        fatal("cannot verify server_host_key");
    if (kex->verify_host_key(server_host_key) == -1)
        fatal("server_host_key verification failed");

    /* DH parameter f, server public DH key */
    if ((dh_server_pub = BN_new()) == NULL)
        fatal("dh_server_pub == NULL");
    packet_get_bignum2(dh_server_pub);

#ifdef DEBUG_KEXDH
    fprintf(stderr, "dh_server_pub= ");
    BN_print_fp(stderr, dh_server_pub);
    fprintf(stderr, "\n");
    debug("bits %d", BN_num_bits(dh_server_pub));
#endif

    /* signed H */
    signature = packet_get_string(&slen);
    packet_check_eom();

    if (!dh_pub_is_valid(dh, dh_server_pub))
        packet_disconnect("bad server public DH value");

    klen = DH_size(dh);
    kbuf = xmalloc(klen);
    if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0)
        fatal("DH_compute_key: failed");
#ifdef DEBUG_KEXDH
    dump_digest("shared secret", kbuf, kout);
#endif
    if ((shared_secret = BN_new()) == NULL)
        fatal("kexdh_client: BN_new failed");
    if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
        fatal("kexdh_client: BN_bin2bn failed");
    memset(kbuf, 0, klen);
    free(kbuf);

    /* calc and verify H */
    kex_dh_hash(
        kex->client_version_string,
        kex->server_version_string,
        buffer_ptr(&kex->my), buffer_len(&kex->my),
        buffer_ptr(&kex->peer), buffer_len(&kex->peer),
        server_host_key_blob, sbloblen,
        dh->pub_key,
        dh_server_pub,
        shared_secret,
        &hash, &hashlen
    );
    free(server_host_key_blob);
    BN_clear_free(dh_server_pub);
    DH_free(dh);

    if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
        fatal("key_verify failed for server_host_key");
    key_free(server_host_key);
    free(signature);

    /* save session id */
    if (kex->session_id == NULL) {
        kex->session_id_len = hashlen;
        kex->session_id = xmalloc(kex->session_id_len);
        memcpy(kex->session_id, hash, kex->session_id_len);
    }

    kex_derive_keys_bn(kex, hash, hashlen, shared_secret);
    BN_clear_free(shared_secret);
    kex_finish(kex);
}
コード例 #19
0
ファイル: bn_gcd.c プロジェクト: busterb/libssl-openbsd
BIGNUM *
BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
{
	BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
	BIGNUM *ret = NULL;
	int sign;

	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) ||
	    (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
		return BN_mod_inverse_no_branch(in, a, n, ctx);
	}

	bn_check_top(a);
	bn_check_top(n);

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	B = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	D = BN_CTX_get(ctx);
	M = BN_CTX_get(ctx);
	Y = BN_CTX_get(ctx);
	T = BN_CTX_get(ctx);
	if (T == NULL)
		goto err;

	if (in == NULL)
		R = BN_new();
	else
		R = in;
	if (R == NULL)
		goto err;

	BN_one(X);
	BN_zero(Y);
	if (BN_copy(B, a) == NULL)
		goto err;
	if (BN_copy(A, n) == NULL)
		goto err;
	A->neg = 0;
	if (B->neg || (BN_ucmp(B, A) >= 0)) {
		if (!BN_nnmod(B, B, A, ctx))
			goto err;
	}
	sign = -1;
	/* From  B = a mod |n|,  A = |n|  it follows that
	 *
	 *      0 <= B < A,
	 *     -sign*X*a  ==  B   (mod |n|),
	 *      sign*Y*a  ==  A   (mod |n|).
	 */

	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
		/* Binary inversion algorithm; requires odd modulus.
		 * This is faster than the general algorithm if the modulus
		 * is sufficiently small (about 400 .. 500 bits on 32-bit
		 * sytems, but much more on 64-bit systems) */
		int shift;

		while (!BN_is_zero(B)) {
			/*
			 *      0 < B < |n|,
			 *      0 < A <= |n|,
			 * (1) -sign*X*a  ==  B   (mod |n|),
			 * (2)  sign*Y*a  ==  A   (mod |n|)
			 */

			/* Now divide  B  by the maximum possible power of two in the integers,
			 * and divide  X  by the same value mod |n|.
			 * When we're done, (1) still holds. */
			shift = 0;
			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
			{
				shift++;

				if (BN_is_odd(X)) {
					if (!BN_uadd(X, X, n))
						goto err;
				}
				/* now X is even, so we can easily divide it by two */
				if (!BN_rshift1(X, X))
					goto err;
			}
			if (shift > 0) {
				if (!BN_rshift(B, B, shift))
					goto err;
			}


			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
			shift = 0;
			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
			{
				shift++;

				if (BN_is_odd(Y)) {
					if (!BN_uadd(Y, Y, n))
						goto err;
				}
				/* now Y is even */
				if (!BN_rshift1(Y, Y))
					goto err;
			}
			if (shift > 0) {
				if (!BN_rshift(A, A, shift))
					goto err;
			}


			/* We still have (1) and (2).
			 * Both  A  and  B  are odd.
			 * The following computations ensure that
			 *
			 *     0 <= B < |n|,
			 *      0 < A < |n|,
			 * (1) -sign*X*a  ==  B   (mod |n|),
			 * (2)  sign*Y*a  ==  A   (mod |n|),
			 *
			 * and that either  A  or  B  is even in the next iteration.
			 */
			if (BN_ucmp(B, A) >= 0) {
				/* -sign*(X + Y)*a == B - A  (mod |n|) */
				if (!BN_uadd(X, X, Y))
					goto err;
				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
				 * actually makes the algorithm slower */
				if (!BN_usub(B, B, A))
					goto err;
			} else {
				/*  sign*(X + Y)*a == A - B  (mod |n|) */
				if (!BN_uadd(Y, Y, X))
					goto err;
				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
				if (!BN_usub(A, A, B))
					goto err;
			}
		}
	} else {
		/* general inversion algorithm */

		while (!BN_is_zero(B)) {
			BIGNUM *tmp;

			/*
			 *      0 < B < A,
			 * (*) -sign*X*a  ==  B   (mod |n|),
			 *      sign*Y*a  ==  A   (mod |n|)
			 */

			/* (D, M) := (A/B, A%B) ... */
			if (BN_num_bits(A) == BN_num_bits(B)) {
				if (!BN_one(D))
					goto err;
				if (!BN_sub(M, A, B))
					goto err;
			} else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
				/* A/B is 1, 2, or 3 */
				if (!BN_lshift1(T, B))
					goto err;
				if (BN_ucmp(A, T) < 0) {
					/* A < 2*B, so D=1 */
					if (!BN_one(D))
						goto err;
					if (!BN_sub(M, A, B))
						goto err;
				} else {
					/* A >= 2*B, so D=2 or D=3 */
					if (!BN_sub(M, A, T))
						goto err;
					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
						if (BN_ucmp(A, D) < 0) {
						/* A < 3*B, so D=2 */
						if (!BN_set_word(D, 2))
							goto err;
						/* M (= A - 2*B) already has the correct value */
					} else {
						/* only D=3 remains */
						if (!BN_set_word(D, 3))
							goto err;
						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
						if (!BN_sub(M, M, B))
							goto err;
					}
				}
			} else {
				if (!BN_div(D, M, A, B, ctx))
					goto err;
			}

			/* Now
			 *      A = D*B + M;
			 * thus we have
			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
			 */
			tmp = A; /* keep the BIGNUM object, the value does not matter */

			/* (A, B) := (B, A mod B) ... */
			A = B;
			B = M;
			/* ... so we have  0 <= B < A  again */

			/* Since the former  M  is now  B  and the former  B  is now  A,
			 * (**) translates into
			 *       sign*Y*a  ==  D*A + B    (mod |n|),
			 * i.e.
			 *       sign*Y*a - D*A  ==  B    (mod |n|).
			 * Similarly, (*) translates into
			 *      -sign*X*a  ==  A          (mod |n|).
			 *
			 * Thus,
			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
			 * i.e.
			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
			 *
			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
			 *      -sign*X*a  ==  B   (mod |n|),
			 *       sign*Y*a  ==  A   (mod |n|).
			 * Note that  X  and  Y  stay non-negative all the time.
			 */

			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
			if (BN_is_one(D)) {
				if (!BN_add(tmp, X, Y))
					goto err;
			} else {
				if (BN_is_word(D, 2)) {
					if (!BN_lshift1(tmp, X))
						goto err;
				} else if (BN_is_word(D, 4)) {
					if (!BN_lshift(tmp, X, 2))
						goto err;
				} else if (D->top == 1) {
					if (!BN_copy(tmp, X))
						goto err;
					if (!BN_mul_word(tmp, D->d[0]))
						goto err;
				} else {
					if (!BN_mul(tmp, D,X, ctx))
						goto err;
				}
				if (!BN_add(tmp, tmp, Y))
					goto err;
			}

			M = Y; /* keep the BIGNUM object, the value does not matter */
			Y = X;
			X = tmp;
			sign = -sign;
		}
	}

	/*
	 * The while loop (Euclid's algorithm) ends when
	 *      A == gcd(a,n);
	 * we have
	 *       sign*Y*a  ==  A  (mod |n|),
	 * where  Y  is non-negative.
	 */

	if (sign < 0) {
		if (!BN_sub(Y, n, Y))
			goto err;
	}
	/* Now  Y*a  ==  A  (mod |n|).  */

	if (BN_is_one(A)) {
		/* Y*a == 1  (mod |n|) */
		if (!Y->neg && BN_ucmp(Y, n) < 0) {
			if (!BN_copy(R, Y))
				goto err;
		} else {
			if (!BN_nnmod(R, Y,n, ctx))
				goto err;
		}
	} else {
		BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
		goto err;
	}
	ret = R;

err:
	if ((ret == NULL) && (in == NULL))
		BN_free(R);
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return (ret);
}
コード例 #20
0
ファイル: dh.c プロジェクト: KennethL/otp
ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */
    DH *dh_params = NULL;
    int mpint; /* 0 or 4 */

    {
        ERL_NIF_TERM head, tail;
        BIGNUM
            *dh_p = NULL,
            *dh_g = NULL,
            *priv_key_in = NULL;
        unsigned long
            len = 0;

        if (!(get_bn_from_bin(env, argv[0], &priv_key_in)
              || argv[0] == atom_undefined)
            || !enif_get_list_cell(env, argv[1], &head, &tail)
            || !get_bn_from_bin(env, head, &dh_p)
            || !enif_get_list_cell(env, tail, &head, &tail)
            || !get_bn_from_bin(env, head, &dh_g)
            || !enif_is_empty_list(env, tail)
            || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)
            || !enif_get_ulong(env, argv[3], &len)

            /* Load dh_params with values to use by the generator.
               Mem mgmnt transfered from dh_p etc to dh_params */
            || !(dh_params = DH_new())
            || (priv_key_in && !DH_set0_key(dh_params, NULL, priv_key_in))
            || !DH_set0_pqg(dh_params, dh_p, NULL, dh_g)
            ) {
            if (priv_key_in) BN_free(priv_key_in);
            if (dh_p) BN_free(dh_p);
            if (dh_g) BN_free(dh_g);
            if (dh_params) DH_free(dh_params);
            return enif_make_badarg(env);
        }

        if (len) {
            if (len < BN_num_bits(dh_p))
                DH_set_length(dh_params, len);
            else {
                if (priv_key_in) BN_free(priv_key_in);
                if (dh_p) BN_free(dh_p);
                if (dh_g) BN_free(dh_g);
                if (dh_params) DH_free(dh_params);
                return enif_make_badarg(env);
            }
        }
    }

#ifdef HAS_EVP_PKEY_CTX
    {
        EVP_PKEY_CTX *ctx;
        EVP_PKEY *dhkey, *params;
        int success;

        params = EVP_PKEY_new();
        success = EVP_PKEY_set1_DH(params, dh_params);   /* set the key referenced by params to dh_params... */
        DH_free(dh_params);                              /* ...dh_params (and params) must be freed */
        if (!success) return atom_error;

        ctx = EVP_PKEY_CTX_new(params, NULL);
        EVP_PKEY_free(params);
        if (!ctx) {
            return atom_error;
        }

        if (!EVP_PKEY_keygen_init(ctx)) {
            /* EVP_PKEY_CTX_free(ctx); */
            return atom_error;
        }

        dhkey = EVP_PKEY_new();
        if (!EVP_PKEY_keygen(ctx, &dhkey)) {         /* "performs a key generation operation, the ... */
                                                     /*... generated key is written to ppkey." (=last arg) */
             /* EVP_PKEY_CTX_free(ctx); */
             /* EVP_PKEY_free(dhkey); */
             return atom_error;
        }

        dh_params = EVP_PKEY_get1_DH(dhkey); /* return the referenced key. dh_params and dhkey must be freed */
        EVP_PKEY_free(dhkey);
        if (!dh_params) {
            /* EVP_PKEY_CTX_free(ctx); */
            return atom_error;
        }
        EVP_PKEY_CTX_free(ctx);
    }
#else
    if (!DH_generate_key(dh_params)) return atom_error;
#endif
    {
        unsigned char *pub_ptr, *prv_ptr;
        int pub_len, prv_len;
        ERL_NIF_TERM ret_pub, ret_prv;
        const BIGNUM *pub_key_gen, *priv_key_gen;

        DH_get0_key(dh_params,
                    &pub_key_gen, &priv_key_gen); /* Get pub_key_gen and priv_key_gen.
                                                     "The values point to the internal representation of
                                                     the public key and private key values. This memory
                                                     should not be freed directly." says man */
        pub_len = BN_num_bytes(pub_key_gen);
        prv_len = BN_num_bytes(priv_key_gen);
        pub_ptr = enif_make_new_binary(env, pub_len+mpint, &ret_pub);
        prv_ptr = enif_make_new_binary(env, prv_len+mpint, &ret_prv);
        if (mpint) {
            put_int32(pub_ptr, pub_len); pub_ptr += 4;
            put_int32(prv_ptr, prv_len); prv_ptr += 4;
        }
        BN_bn2bin(pub_key_gen, pub_ptr);
        BN_bn2bin(priv_key_gen, prv_ptr);
        ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len);
        ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len);

        DH_free(dh_params);

        return enif_make_tuple2(env, ret_pub, ret_prv);
    }
}
コード例 #21
0
ファイル: rsa_impl.c プロジェクト: aaapei/libquic
int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
                           size_t max_out, const uint8_t *in, size_t in_len,
                           int padding) {
  const unsigned rsa_size = RSA_size(rsa);
  BIGNUM *f, *result;
  int ret = 0;
  int r = -1;
  uint8_t *buf = NULL;
  BN_CTX *ctx = NULL;

  if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
    return 0;
  }

  if (BN_ucmp(rsa->n, rsa->e) <= 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
    return 0;
  }

  if (max_out < rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
    return 0;
  }

  /* for large moduli, enforce exponent limit */
  if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
      BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
    return 0;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }

  BN_CTX_start(ctx);
  f = BN_CTX_get(ctx);
  result = BN_CTX_get(ctx);
  if (padding == RSA_NO_PADDING) {
    buf = out;
  } else {
    /* Allocate a temporary buffer to hold the padded plaintext. */
    buf = OPENSSL_malloc(rsa_size);
    if (buf == NULL) {
      OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }
  if (!f || !result) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (in_len != rsa_size) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
    goto err;
  }

  if (BN_bin2bn(in, in_len, f) == NULL) {
    goto err;
  }

  if (BN_ucmp(f, rsa->n) >= 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
    goto err;
  }

  if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
    if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) {
      goto err;
    }
  }

  if (!rsa->meth->bn_mod_exp(result, f, rsa->e, rsa->n, ctx, rsa->mont_n)) {
    goto err;
  }

  if (!BN_bn2bin_padded(buf, rsa_size, result)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  switch (padding) {
    case RSA_PKCS1_PADDING:
      r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size);
      break;
    case RSA_NO_PADDING:
      r = rsa_size;
      break;
    default:
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
      goto err;
  }

  if (r < 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
  } else {
    *out_len = r;
    ret = 1;
  }

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  if (padding != RSA_NO_PADDING && buf != NULL) {
    OPENSSL_cleanse(buf, rsa_size);
    OPENSSL_free(buf);
  }
  return ret;
}
コード例 #22
0
ファイル: eap_pwd.c プロジェクト: 09sea98/rtl8188eu
static struct wpabuf *
eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
			    struct eap_method_ret *ret,
			    const struct wpabuf *reqData,
			    const u8 *payload, size_t payload_len)
{
	struct eap_pwd_id *id;
	struct wpabuf *resp;

	if (data->state != PWD_ID_Req) {
		ret->ignore = TRUE;
		return NULL;
	}

	if (payload_len < sizeof(struct eap_pwd_id)) {
		ret->ignore = TRUE;
		return NULL;
	}

	id = (struct eap_pwd_id *) payload;
	data->group_num = be_to_host16(id->group_num);
	if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) ||
	    (id->prf != EAP_PWD_DEFAULT_PRF)) {
		ret->ignore = TRUE;
		return NULL;
	}

	wpa_printf(MSG_DEBUG, "EAP-PWD (peer): server said group %d",
		   data->group_num);

	data->id_server = os_malloc(payload_len - sizeof(struct eap_pwd_id));
	if (data->id_server == NULL) {
		wpa_printf(MSG_INFO, "EAP-PWD: memory allocation id fail");
		return NULL;
	}
	data->id_server_len = payload_len - sizeof(struct eap_pwd_id);
	os_memcpy(data->id_server, id->identity, data->id_server_len);
	wpa_hexdump_ascii(MSG_INFO, "EAP-PWD (peer): server sent id of",
			  data->id_server, data->id_server_len);

	if ((data->grp = (EAP_PWD_group *) os_malloc(sizeof(EAP_PWD_group))) ==
	    NULL) {
		wpa_printf(MSG_INFO, "EAP-PWD: failed to allocate memory for "
			   "group");
		return NULL;
	}

	/* compute PWE */
	if (compute_password_element(data->grp, data->group_num,
				     data->password, data->password_len,
				     data->id_server, data->id_server_len,
				     data->id_peer, data->id_peer_len,
				     id->token)) {
		wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE");
		return NULL;
	}

	wpa_printf(MSG_INFO, "EAP-PWD (peer): computed %d bit PWE...",
		   BN_num_bits(data->grp->prime));

	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD,
			     1 + sizeof(struct eap_pwd_id) + data->id_peer_len,
			     EAP_CODE_RESPONSE, eap_get_id(reqData));
	if (resp == NULL)
		return NULL;

	wpabuf_put_u8(resp, EAP_PWD_OPCODE_ID_EXCH);
	wpabuf_put_be16(resp, data->group_num);
	wpabuf_put_u8(resp, EAP_PWD_DEFAULT_RAND_FUNC);
	wpabuf_put_u8(resp, EAP_PWD_DEFAULT_PRF);
	wpabuf_put_data(resp, id->token, sizeof(id->token));
	wpabuf_put_u8(resp, EAP_PWD_PREP_NONE);
	wpabuf_put_data(resp, data->id_peer, data->id_peer_len);

	eap_pwd_state(data, PWD_Commit_Req);

	return resp;
}
コード例 #23
0
ファイル: rsa_impl.c プロジェクト: aaapei/libquic
int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
                                   BIGNUM *e_value, BN_GENCB *cb) {
  BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
  BIGNUM local_r0, local_d, local_p;
  BIGNUM *pr0, *d, *p;
  int prime_bits, ok = -1, n = 0, i, j;
  BN_CTX *ctx = NULL;
  STACK_OF(RSA_additional_prime) *additional_primes = NULL;

  if (num_primes < 2) {
    ok = 0; /* we set our own err */
    OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES);
    goto err;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  r0 = BN_CTX_get(ctx);
  r1 = BN_CTX_get(ctx);
  r2 = BN_CTX_get(ctx);
  r3 = BN_CTX_get(ctx);
  if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) {
    goto err;
  }

  if (num_primes > 2) {
    additional_primes = sk_RSA_additional_prime_new_null();
    if (additional_primes == NULL) {
      goto err;
    }
  }

  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime));
    if (ap == NULL) {
      goto err;
    }
    memset(ap, 0, sizeof(RSA_additional_prime));
    ap->prime = BN_new();
    ap->exp = BN_new();
    ap->coeff = BN_new();
    ap->r = BN_new();
    if (ap->prime == NULL ||
        ap->exp == NULL ||
        ap->coeff == NULL ||
        ap->r == NULL ||
        !sk_RSA_additional_prime_push(additional_primes, ap)) {
      RSA_additional_prime_free(ap);
      goto err;
    }
  }

  /* We need the RSA components non-NULL */
  if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->d && ((rsa->d = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->e && ((rsa->e = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->p && ((rsa->p = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->q && ((rsa->q = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) {
    goto err;
  }

  if (!BN_copy(rsa->e, e_value)) {
    goto err;
  }

  /* generate p and q */
  prime_bits = (bits + (num_primes - 1)) / num_primes;
  for (;;) {
    if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) ||
        !BN_sub(r2, rsa->p, BN_value_one()) ||
        !BN_gcd(r1, r2, rsa->e, ctx)) {
      goto err;
    }
    if (BN_is_one(r1)) {
      break;
    }
    if (!BN_GENCB_call(cb, 2, n++)) {
      goto err;
    }
  }
  if (!BN_GENCB_call(cb, 3, 0)) {
    goto err;
  }
  prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1);
  for (;;) {
    /* When generating ridiculously small keys, we can get stuck
     * continually regenerating the same prime values. Check for
     * this and bail if it happens 3 times. */
    unsigned int degenerate = 0;
    do {
      if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) {
        goto err;
      }
    } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
    if (degenerate == 3) {
      ok = 0; /* we set our own err */
      OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
      goto err;
    }
    if (!BN_sub(r2, rsa->q, BN_value_one()) ||
        !BN_gcd(r1, r2, rsa->e, ctx)) {
      goto err;
    }
    if (BN_is_one(r1)) {
      break;
    }
    if (!BN_GENCB_call(cb, 2, n++)) {
      goto err;
    }
  }

  if (!BN_GENCB_call(cb, 3, 1) ||
      !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
    goto err;
  }

  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(additional_primes, i - 2);
    prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) /
                 (num_primes - i);

    for (;;) {
      if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) {
        goto err;
      }
      if (BN_cmp(rsa->p, ap->prime) == 0 ||
          BN_cmp(rsa->q, ap->prime) == 0) {
        continue;
      }

      for (j = 0; j < i - 2; j++) {
        if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime,
                   ap->prime) == 0) {
          break;
        }
      }
      if (j != i - 2) {
        continue;
      }

      if (!BN_sub(r2, ap->prime, BN_value_one()) ||
          !BN_gcd(r1, r2, rsa->e, ctx)) {
        goto err;
      }

      if (!BN_is_one(r1)) {
        continue;
      }
      if (i != num_primes - 1) {
        break;
      }

      /* For the last prime we'll check that it makes n large enough. In the
       * two prime case this isn't a problem because we generate primes with
       * the top two bits set and so the product is always of the expected
       * size. In the multi prime case, this doesn't follow. */
      if (!BN_mul(r1, rsa->n, ap->prime, ctx)) {
        goto err;
      }
      if (BN_num_bits(r1) == (unsigned) bits) {
        break;
      }

      if (!BN_GENCB_call(cb, 2, n++)) {
        goto err;
      }
    }

    /* ap->r is is the product of all the primes prior to the current one
     * (including p and q). */
    if (!BN_copy(ap->r, rsa->n)) {
      goto err;
    }
    if (i == num_primes - 1) {
      /* In the case of the last prime, we calculated n as |r1| in the loop
       * above. */
      if (!BN_copy(rsa->n, r1)) {
        goto err;
      }
    } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) {
      goto err;
    }

    if (!BN_GENCB_call(cb, 3, 1)) {
      goto err;
    }
  }

  if (BN_cmp(rsa->p, rsa->q) < 0) {
    tmp = rsa->p;
    rsa->p = rsa->q;
    rsa->q = tmp;
  }

  /* calculate d */
  if (!BN_sub(r1, rsa->p, BN_value_one())) {
    goto err; /* p-1 */
  }
  if (!BN_sub(r2, rsa->q, BN_value_one())) {
    goto err; /* q-1 */
  }
  if (!BN_mul(r0, r1, r2, ctx)) {
    goto err; /* (p-1)(q-1) */
  }
  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(additional_primes, i - 2);
    if (!BN_sub(r3, ap->prime, BN_value_one()) ||
        !BN_mul(r0, r0, r3, ctx)) {
      goto err;
    }
  }
  pr0 = &local_r0;
  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
  if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
    goto err; /* d */
  }

  /* set up d for correct BN_FLG_CONSTTIME flag */
  d = &local_d;
  BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);

  /* calculate d mod (p-1) */
  if (!BN_mod(rsa->dmp1, d, r1, ctx)) {
    goto err;
  }

  /* calculate d mod (q-1) */
  if (!BN_mod(rsa->dmq1, d, r2, ctx)) {
    goto err;
  }

  /* calculate inverse of q mod p */
  p = &local_p;
  BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);

  if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
    goto err;
  }

  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(additional_primes, i - 2);
    if (!BN_sub(ap->exp, ap->prime, BN_value_one()) ||
        !BN_mod(ap->exp, rsa->d, ap->exp, ctx) ||
        !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) {
      goto err;
    }
  }

  ok = 1;
  rsa->additional_primes = additional_primes;
  additional_primes = NULL;

err:
  if (ok == -1) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
    ok = 0;
  }
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  sk_RSA_additional_prime_pop_free(additional_primes,
                                   RSA_additional_prime_free);
  return ok;
}
コード例 #24
0
ファイル: dh_key.c プロジェクト: cdaffara/symbiandump-os2
static int generate_key(DH *dh)
	{
	int ok=0;
	int generate_new_key=0;
	unsigned l;
	BN_CTX *ctx;
	BN_MONT_CTX *mont=NULL;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

	ctx = BN_CTX_new();
	if (ctx == NULL) goto err;

	if (dh->priv_key == NULL)
		{
		priv_key=BN_new();
		if (priv_key == NULL) goto err;
		generate_new_key=1;
		}
	else
		priv_key=dh->priv_key;

	if (dh->pub_key == NULL)
		{
		pub_key=BN_new();
		if (pub_key == NULL) goto err;
		}
	else
		pub_key=dh->pub_key;


	if (dh->flags & DH_FLAG_CACHE_MONT_P)
		{
		mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
				CRYPTO_LOCK_DH, dh->p, ctx);
		if (!mont)
			goto err;
		}

	if (generate_new_key)
		{
		l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
		if (!BN_rand(priv_key, l, 0, 0)) goto err;
		}

	{
		BIGNUM local_prk;
		BIGNUM *prk;

		if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
			{
			BN_init(&local_prk);
			prk = &local_prk;
			BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
			}
		else
			prk = priv_key;

		if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err;
	}
		
	dh->pub_key=pub_key;
	dh->priv_key=priv_key;
	ok=1;
err:
	if (ok != 1)
		DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);

	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
	BN_CTX_free(ctx);
	return(ok);
	}
コード例 #25
0
ファイル: prime.c プロジェクト: AxiomaAbsurdo/time_web_app
static int probable_prime(BIGNUM *rnd, int bits) {
  int i;
  uint16_t mods[NUMPRIMES];
  BN_ULONG delta;
  BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
  char is_single_word = bits <= BN_BITS2;

again:
  if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) {
    return 0;
  }

  // we now have a random number 'rnd' to test.
  for (i = 1; i < NUMPRIMES; i++) {
    BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
    if (mod == (BN_ULONG)-1) {
      return 0;
    }
    mods[i] = (uint16_t)mod;
  }
  // If bits is so small that it fits into a single word then we
  // additionally don't want to exceed that many bits.
  if (is_single_word) {
    BN_ULONG size_limit;
    if (bits == BN_BITS2) {
      // Avoid undefined behavior.
      size_limit = ~((BN_ULONG)0) - BN_get_word(rnd);
    } else {
      size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1;
    }
    if (size_limit < maxdelta) {
      maxdelta = size_limit;
    }
  }
  delta = 0;

loop:
  if (is_single_word) {
    BN_ULONG rnd_word = BN_get_word(rnd);

    // In the case that the candidate prime is a single word then
    // we check that:
    //   1) It's greater than primes[i] because we shouldn't reject
    //      3 as being a prime number because it's a multiple of
    //      three.
    //   2) That it's not a multiple of a known prime. We don't
    //      check that rnd-1 is also coprime to all the known
    //      primes because there aren't many small primes where
    //      that's true.
    for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) {
      if ((mods[i] + delta) % primes[i] == 0) {
        delta += 2;
        if (delta > maxdelta) {
          goto again;
        }
        goto loop;
      }
    }
  } else {
    for (i = 1; i < NUMPRIMES; i++) {
      // check that rnd is not a prime and also
      // that gcd(rnd-1,primes) == 1 (except for 2)
      if (((mods[i] + delta) % primes[i]) <= 1) {
        delta += 2;
        if (delta > maxdelta) {
          goto again;
        }
        goto loop;
      }
    }
  }

  if (!BN_add_word(rnd, delta)) {
    return 0;
  }
  if (BN_num_bits(rnd) != (unsigned)bits) {
    goto again;
  }

  return 1;
}
コード例 #26
0
int
auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
{
	char line[SSH_MAX_PUBKEY_BYTES], *file;
	int allowed = 0;
	u_int bits;
	FILE *f;
	u_long linenum = 0;
	Key *key;

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

	/* The authorized keys. */
	file = authorized_keys_file(pw);
	debug("trying public RSA key file %s", file);
	f = auth_openkeyfile(file, pw, options.strict_modes);
	if (!f) {
		xfree(file);
		restore_uid();
		return (0);
	}

	/* Flag indicating whether the key is allowed. */
	allowed = 0;

	key = key_new(KEY_RSA1);

	/*
	 * Go though the accepted keys, looking for the current key.  If
	 * found, perform a challenge-response dialog to verify that the
	 * user really has the corresponding private key.
	 */
	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
		char *cp;
		char *key_options;
		int keybits;
		char *fp;

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		/*
		 * Check if there are options for this key, and if so,
		 * save their starting address and skip the option part
		 * for now.  If there are no options, set the starting
		 * address to NULL.
		 */
		if (*cp < '0' || *cp > '9') {
			int quoted = 0;
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
		} else
			key_options = NULL;

		/* Parse the key from the line. */
		if (hostfile_read_key(&cp, &bits, key) == 0) {
			debug("%.100s, line %lu: non ssh1 key syntax",
			    file, linenum);
			continue;
		}
		/* cp now points to the comment part. */

		/* Check if the we have found the desired key (identified by its modulus). */
		if (BN_cmp(key->rsa->n, client_n) != 0)
			continue;

		/* check the real bits  */
		keybits = BN_num_bits(key->rsa->n);
		if (keybits < 0 || bits != (u_int)keybits)
			logit("Warning: %s, line %lu: keysize mismatch: "
			    "actual %d vs. announced %d.",
			    file, linenum, BN_num_bits(key->rsa->n), bits);

		/* Never accept a revoked key */
		if (auth_key_is_revoked(key))
			break;

		if (blacklisted_key(key)) {
			fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
			if (options.permit_blacklisted_keys)
				logit("Public key %s blacklisted (see "
				    "ssh-vulnkey(1)); continuing anyway", fp);
			else
				logit("Public key %s blacklisted (see "
				    "ssh-vulnkey(1))", fp);
			xfree(fp);
			if (!options.permit_blacklisted_keys)
				continue;
		}

		/* We have found the desired key. */
		/*
		 * If our options do not allow this key to be used,
		 * do not send challenge.
		 */
		if (!auth_parse_options(pw, key_options, file, linenum))
			continue;
		if (key_is_cert_authority)
			continue;
		/* break out, this key is allowed */
		allowed = 1;
		break;
	}

	/* Restore the privileged uid. */
	restore_uid();

	/* Close the file. */
	xfree(file);
	fclose(f);

	/* return key if allowed */
	if (allowed && rkey != NULL)
		*rkey = key;
	else
		key_free(key);
	return (allowed);
}
コード例 #27
0
ファイル: ec_lib.c プロジェクト: Bilibili/openssl
int ec_group_simple_order_bits(const EC_GROUP *group)
{
    if (group->order == NULL)
        return 0;
    return BN_num_bits(group->order);
}
コード例 #28
0
ファイル: sqrt.c プロジェクト: AxiomaAbsurdo/time_web_app
int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
  BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2;
  int ok = 0, last_delta_valid = 0;

  if (in->neg) {
    OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
    return 0;
  }
  if (BN_is_zero(in)) {
    BN_zero(out_sqrt);
    return 1;
  }

  BN_CTX_start(ctx);
  if (out_sqrt == in) {
    estimate = BN_CTX_get(ctx);
  } else {
    estimate = out_sqrt;
  }
  tmp = BN_CTX_get(ctx);
  last_delta = BN_CTX_get(ctx);
  delta = BN_CTX_get(ctx);
  if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) {
    OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  // We estimate that the square root of an n-bit number is 2^{n/2}.
  if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) {
    goto err;
  }

  // This is Newton's method for finding a root of the equation |estimate|^2 -
  // |in| = 0.
  for (;;) {
    // |estimate| = 1/2 * (|estimate| + |in|/|estimate|)
    if (!BN_div(tmp, NULL, in, estimate, ctx) ||
        !BN_add(tmp, tmp, estimate) ||
        !BN_rshift1(estimate, tmp) ||
        // |tmp| = |estimate|^2
        !BN_sqr(tmp, estimate, ctx) ||
        // |delta| = |in| - |tmp|
        !BN_sub(delta, in, tmp)) {
      OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
      goto err;
    }

    delta->neg = 0;
    // The difference between |in| and |estimate| squared is required to always
    // decrease. This ensures that the loop always terminates, but I don't have
    // a proof that it always finds the square root for a given square.
    if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) {
      break;
    }

    last_delta_valid = 1;

    tmp2 = last_delta;
    last_delta = delta;
    delta = tmp2;
  }

  if (BN_cmp(tmp, in) != 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
    goto err;
  }

  ok = 1;

err:
  if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) {
    ok = 0;
  }
  BN_CTX_end(ctx);
  return ok;
}
コード例 #29
0
ファイル: rsa_eay.c プロジェクト: Acidburn0zzz/openssl
static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM *f,*ret;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
		return -1;
		}

	if (BN_ucmp(rsa->n, rsa->e) <= 0)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
		return -1;
		}

	/* for large moduli, enforce exponent limit */
	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
		{
		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
			{
			RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
			return -1;
			}
		}
	
	if ((ctx=BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	f = BN_CTX_get(ctx);
	ret = BN_CTX_get(ctx);
	num=BN_num_bytes(rsa->n);
	buf = OPENSSL_malloc(num);
	if (!f || !ret || !buf)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
		break;
#ifndef OPENSSL_NO_SHA
	case RSA_PKCS1_OAEP_PADDING:
	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
		break;
#endif
	case RSA_SSLV23_PADDING:
		i=RSA_padding_add_SSLv23(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	default:
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,f) == NULL) goto err;
	
	if (BN_ucmp(f, rsa->n) >= 0)
		{
		/* usually the padding functions would catch this */
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
		goto err;
		}

	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
			goto err;

	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
		rsa->_method_mod_n)) goto err;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(ret);
	i=BN_bn2bin(ret,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (buf != NULL) 
		{
		OPENSSL_cleanse(buf,num);
		OPENSSL_free(buf);
		}
	return(r);
	}
コード例 #30
0
ファイル: rsa-sign.c プロジェクト: duanlv/u-boot-1
int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
{
	BIGNUM *modulus, *r_squared;
	uint64_t exponent;
	uint32_t n0_inv;
	int parent, node;
	char name[100];
	int ret;
	int bits;
	RSA *rsa;

	debug("%s: Getting verification data\n", __func__);
	ret = rsa_get_pub_key(info->keydir, info->keyname, &rsa);
	if (ret)
		return ret;
	ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared);
	if (ret)
		return ret;
	bits = BN_num_bits(modulus);
	parent = fdt_subnode_offset(keydest, 0, FIT_SIG_NODENAME);
	if (parent == -FDT_ERR_NOTFOUND) {
		parent = fdt_add_subnode(keydest, 0, FIT_SIG_NODENAME);
		if (parent < 0) {
			ret = parent;
			if (ret != -FDT_ERR_NOSPACE) {
				fprintf(stderr, "Couldn't create signature node: %s\n",
					fdt_strerror(parent));
			}
		}
	}
	if (ret)
		goto done;

	/* Either create or overwrite the named key node */
	snprintf(name, sizeof(name), "key-%s", info->keyname);
	node = fdt_subnode_offset(keydest, parent, name);
	if (node == -FDT_ERR_NOTFOUND) {
		node = fdt_add_subnode(keydest, parent, name);
		if (node < 0) {
			ret = node;
			if (ret != -FDT_ERR_NOSPACE) {
				fprintf(stderr, "Could not create key subnode: %s\n",
					fdt_strerror(node));
			}
		}
	} else if (node < 0) {
		fprintf(stderr, "Cannot select keys parent: %s\n",
			fdt_strerror(node));
		ret = node;
	}

	if (!ret) {
		ret = fdt_setprop_string(keydest, node, "key-name-hint",
				 info->keyname);
	}
	if (!ret)
		ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits);
	if (!ret)
		ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv);
	if (!ret) {
		ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent);
	}
	if (!ret) {
		ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus,
				     bits);
	}
	if (!ret) {
		ret = fdt_add_bignum(keydest, node, "rsa,r-squared", r_squared,
				     bits);
	}
	if (!ret) {
		ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP,
					 info->algo->name);
	}
	if (!ret && info->require_keys) {
		ret = fdt_setprop_string(keydest, node, "required",
					 info->require_keys);
	}
done:
	BN_free(modulus);
	BN_free(r_squared);
	if (ret)
		return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;

	return 0;
}