Exemplo n.º 1
0
static int _rngfips_ctx_reinit(struct fips_ctx *fctx)
{
	int ret;

	/* strong */
	ret = drbg_reseed(&fctx->strong_context);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* normal */
	ret = drbg_reseed(&fctx->normal_context);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* nonce */
	ret = drbg_reseed(&fctx->nonce_context);
	if (ret < 0)
		return gnutls_assert_val(ret);

#ifdef HAVE_GETPID
	fctx->pid = getpid();
#endif
	return 0;
}
Exemplo n.º 2
0
/**
 * Generate pseudorandom bits using DRBG
 *
 * @v state		Algorithm state
 * @v additional	Additional input
 * @v additional_len	Length of additional input
 * @v prediction_resist	Prediction resistance is required
 * @v data		Output buffer
 * @v len		Length of output buffer
 * @ret rc		Return status code
 *
 * This is the Generate_function defined in ANS X9.82 Part 3-2007
 * Section 9.4 (NIST SP 800-90 Section 9.3).
 *
 * Requests must be for an integral number of bytes.  Only a single
 * security strength is supported.  Prediction resistance is supported
 * if requested.
 */
int drbg_generate ( struct drbg_state *state, const void *additional,
		    size_t additional_len, int prediction_resist,
		    void *data, size_t len ) {
	int rc;

	DBGC ( state, "DRBG %p generate\n", state );

	/* Sanity checks */
	assert ( state != NULL );
	assert ( data != NULL );

	/* 1.  Using state_handle, obtain the current internal state
	 *     for the instantiation.  If state_handle indicates an
	 *     invalid or empty internal state, then return an ERROR_FLAG.
	 *
	 * (Almost nothing to do since the memory holding the internal
	 * state was passed in by the caller.)
	 */
	if ( ! state->valid ) {
		DBGC ( state, "DRBG %p not valid\n", state );
		return -EINVAL;
	}

	/* 2.  If requested_number_of_bits >
	 *     max_number_of_bits_per_request, then return an
	 *     ERROR_FLAG.
	 */
	if ( len > DRBG_MAX_GENERATED_LEN_BYTES ) {
		DBGC ( state, "DRBG %p request too long (%zd bytes)\n",
		       state, len );
		return -ERANGE;
	}

	/* 3.  If requested_security_strength > the security_strength
	 *     indicated in the internal state, then return an
	 *     ERROR_FLAG.
	 *
	 * (Nothing to do since only a single security strength is
	 * supported.)
	 */

	/* 4.  If the length of the additional_input >
	 *     max_additional_input_length, then return an ERROR_FLAG.
	 */
	if ( additional_len > DRBG_MAX_ADDITIONAL_LEN_BYTES ) {
		DBGC ( state, "DRBG %p additional input too long (%zd bytes)\n",
		       state, additional_len );
		return -ERANGE;
	}

	/* 5.  If prediction_resistance_request is set, and
	 *     prediction_resistance_flag is not set, then return an
	 *     ERROR_FLAG.
	 *
	 * (Nothing to do since prediction resistance is always
	 * supported.)
	 */

	/* 6.  Clear the reseed_required_flag. */
	state->reseed_required = 0;

 step_7:
	/* 7.  If reseed_required_flag is set, or if
	 *     prediction_resistance_request is set, then
	 */
	if ( state->reseed_required || prediction_resist ) {

		/* 7.1  status = Reseed_function ( state_handle,
		 *      prediction_resistance_request,
		 *      additional_input )
		 * 7.2  If status indicates an ERROR, then return
		 *      status.
		 */
		if ( ( rc = drbg_reseed ( state, additional,
					  additional_len ) ) != 0 ) {
			DBGC ( state, "DRBG %p could not reseed: %s\n",
			       state, strerror ( rc ) );
			return rc;
		}

		/* 7.3  Using state_handle, obtain the new internal
		 *      state.
		 *
		 * (Nothing to do since the internal state has been
		 * updated in-situ.)
		 */

		/* 7.4  additional_input = the Null string. */
		additional = NULL;
		additional_len = 0;

		/* 7.5  Clear the reseed_required_flag. */
		state->reseed_required = 0;
	}

	/* 8.  ( status, pseudorandom_bits, new_working_state ) =
	 *     Generate_algorithm ( working_state,
	 *     requested_number_of_bits, additional_input ).
	 */
	rc = drbg_generate_algorithm ( state, additional, additional_len,
				       data, len );

	/* 9.  If status indicates that a reseed is required before
	 *     the requested bits can be generated, then
	 */
	if ( rc != 0 ) {

		/* 9.1  Set the reseed_required_flag. */
		state->reseed_required = 1;

		/* 9.2  If the prediction_resistance_flag is set, then
		 *      set the prediction_resistance_request
		 *      indication.
		 */
		prediction_resist = 1;

		/* 9.3  Go to step 7. */
		goto step_7;
	}

	/* 10.  Replace the old working_state in the internal state
	 *      indicated by state_handle with the values of
	 *      new_working_state.
	 *
	 * (Nothing to do since the working state has already been
	 * updated in-situ.)
	 */

	/* 11.  Return SUCCESS and pseudorandom_bits. */
	return 0;
}