Commit a1e7883e authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add meaningful error codes to DRBG.

parent dd0d2df5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ L NONE crypto/x509/x509_vfy.h NONE
L NONE		crypto/ec/ec_lcl.h		NONE
L NONE		crypto/asn1/asn_lcl.h		NONE
L NONE		crypto/cms/cms_lcl.h		NONE
L NONE		fips/rand/fips_rand.h		NONE


F RSAREF_F_RSA_BN2BIN
+18 −0
Original line number Diff line number Diff line
@@ -83,6 +83,10 @@ static ERR_STRING_DATA FIPS_str_functs[]=
{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA),	"fips_check_rsa"},
{ERR_FUNC(FIPS_F_FIPS_CIPHERINIT),	"FIPS_CIPHERINIT"},
{ERR_FUNC(FIPS_F_FIPS_DIGESTINIT),	"FIPS_DIGESTINIT"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE),	"FIPS_drbg_generate"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE),	"FIPS_drbg_instantiate"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_NEW),	"FIPS_drbg_new"},
{ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED),	"FIPS_drbg_reseed"},
{ERR_FUNC(FIPS_F_FIPS_DSA_CHECK),	"FIPS_DSA_CHECK"},
{ERR_FUNC(FIPS_F_FIPS_MODE_SET),	"FIPS_mode_set"},
{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST),	"fips_pkey_signature_test"},
@@ -107,23 +111,37 @@ static ERR_STRING_DATA FIPS_str_functs[]=

static ERR_STRING_DATA FIPS_str_reasons[]=
	{
{ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG),"additional input too long"},
{ERR_REASON(FIPS_R_ALREADY_INSTANTIATED) ,"already instantiated"},
{ERR_REASON(FIPS_R_CANNOT_READ_EXE)      ,"cannot read exe"},
{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"},
{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
{ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
{ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
{ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY),"error retrieving entropy"},
{ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE),"error retrieving nonce"},
{ERR_REASON(FIPS_R_EXE_DIGEST_DOES_NOT_MATCH),"exe digest does not match"},
{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"},
{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"},
{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"},
{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"},
{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"},
{ERR_REASON(FIPS_R_GENERATE_ERROR)       ,"generate error"},
{ERR_REASON(FIPS_R_INSTANTIATE_ERROR)    ,"instantiate error"},
{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH)   ,"invalid key length"},
{ERR_REASON(FIPS_R_IN_ERROR_STATE)       ,"in error state"},
{ERR_REASON(FIPS_R_KEY_TOO_SHORT)        ,"key too short"},
{ERR_REASON(FIPS_R_NON_FIPS_METHOD)      ,"non fips method"},
{ERR_REASON(FIPS_R_NOT_INSTANTIATED)     ,"not instantiated"},
{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"},
{ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG),"personalisation string too long"},
{ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG),"request too large for drbg"},
{ERR_REASON(FIPS_R_RESEED_ERROR)         ,"reseed error"},
{ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR)    ,"rsa decrypt error"},
{ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR)    ,"rsa encrypt error"},
{ERR_REASON(FIPS_R_SELFTEST_FAILED)      ,"selftest failed"},
{ERR_REASON(FIPS_R_TEST_FAILURE)         ,"test failure"},
{ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE),"unsupported drbg type"},
{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
{0,NULL}
	};
+18 −0
Original line number Diff line number Diff line
@@ -190,6 +190,10 @@ void ERR_load_FIPS_strings(void);
#define FIPS_F_FIPS_CHECK_RSA				 106
#define FIPS_F_FIPS_CIPHERINIT				 128
#define FIPS_F_FIPS_DIGESTINIT				 127
#define FIPS_F_FIPS_DRBG_GENERATE			 132
#define FIPS_F_FIPS_DRBG_INSTANTIATE			 133
#define FIPS_F_FIPS_DRBG_NEW				 134
#define FIPS_F_FIPS_DRBG_RESEED				 135
#define FIPS_F_FIPS_DSA_CHECK				 107
#define FIPS_F_FIPS_MODE_SET				 108
#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST			 109
@@ -211,23 +215,37 @@ void ERR_load_FIPS_strings(void);
#define FIPS_F_SSLEAY_RAND_BYTES			 122

/* Reason codes. */
#define FIPS_R_ADDITIONAL_INPUT_TOO_LONG		 118
#define FIPS_R_ALREADY_INSTANTIATED			 119
#define FIPS_R_CANNOT_READ_EXE				 103
#define FIPS_R_CANNOT_READ_EXE_DIGEST			 104
#define FIPS_R_CONTRADICTING_EVIDENCE			 114
#define FIPS_R_ERROR_INITIALISING_DRBG			 120
#define FIPS_R_ERROR_INSTANTIATING_DRBG			 121
#define FIPS_R_ERROR_RETRIEVING_ENTROPY			 122
#define FIPS_R_ERROR_RETRIEVING_NONCE			 123
#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH		 105
#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH		 110
#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
#define FIPS_R_FIPS_MODE_ALREADY_SET			 102
#define FIPS_R_FIPS_SELFTEST_FAILED			 106
#define FIPS_R_GENERATE_ERROR				 124
#define FIPS_R_INSTANTIATE_ERROR			 125
#define FIPS_R_INVALID_KEY_LENGTH			 109
#define FIPS_R_IN_ERROR_STATE				 126
#define FIPS_R_KEY_TOO_SHORT				 108
#define FIPS_R_NON_FIPS_METHOD				 100
#define FIPS_R_NOT_INSTANTIATED				 127
#define FIPS_R_PAIRWISE_TEST_FAILED			 107
#define FIPS_R_PERSONALISATION_STRING_TOO_LONG		 128
#define FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG		 129
#define FIPS_R_RESEED_ERROR				 130
#define FIPS_R_RSA_DECRYPT_ERROR			 115
#define FIPS_R_RSA_ENCRYPT_ERROR			 116
#define FIPS_R_SELFTEST_FAILED				 101
#define FIPS_R_TEST_FAILURE				 117
#define FIPS_R_UNSUPPORTED_DRBG_TYPE			 131
#define FIPS_R_UNSUPPORTED_PLATFORM			 113

#ifdef  __cplusplus
+90 −15
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/fips_rand.h>
#include "fips_rand_lcl.h"

@@ -80,12 +81,23 @@ static int fips_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags)

DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags)
	{
	int rv;
	DRBG_CTX *dctx;
	dctx = OPENSSL_malloc(sizeof(DRBG_CTX));
	if (!dctx)
		{
		FIPSerr(FIPS_F_FIPS_DRBG_NEW, ERR_R_MALLOC_FAILURE);
		return NULL;
	if (fips_drbg_init(dctx, type, flags) <= 0)
		}
	rv = fips_drbg_init(dctx, type, flags);

	if (rv <= 0)
		{
		if (rv == -2)
			FIPSerr(FIPS_F_FIPS_DRBG_NEW, FIPS_R_UNSUPPORTED_DRBG_TYPE);
		else
			FIPSerr(FIPS_F_FIPS_DRBG_NEW, FIPS_R_ERROR_INITIALISING_DRBG);

		OPENSSL_free(dctx);
		return NULL;
		}
@@ -105,13 +117,32 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx,
	{
	size_t entlen, noncelen;

#if 0
	/* Put here so error script picks them up */
	FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE,
				FIPS_R_PERSONALISATION_STRING_TOO_LONG);
	FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_IN_ERROR_STATE);
	FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ALREADY_INSTANTIATED);
	FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_ENTROPY);
	FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_NONCE);
	FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_INSTANTIATE_ERROR);
#endif

	int r = 0;

	if (perslen > dctx->max_pers)
		return 0;
		{
		r = FIPS_R_PERSONALISATION_STRING_TOO_LONG;
		goto end;
		}

	if (dctx->status != DRBG_STATUS_UNINITIALISED)
		{
		/* error */
		return 0;
		if (dctx->status == DRBG_STATUS_ERROR)
			r = FIPS_R_IN_ERROR_STATE;
		else
			r = FIPS_R_ALREADY_INSTANTIATED;
		goto end;
		}

	dctx->status = DRBG_STATUS_ERROR;
@@ -120,7 +151,10 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx,
				dctx->min_entropy, dctx->max_entropy);

	if (entlen < dctx->min_entropy || entlen > dctx->max_entropy)
		{
		r = FIPS_R_ERROR_RETRIEVING_ENTROPY;
		goto end;
		}

	if (dctx->max_nonce > 0)
		{
@@ -130,7 +164,10 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx,
					dctx->min_nonce, dctx->max_nonce);

		if (noncelen < dctx->min_nonce || noncelen > dctx->max_nonce)
			{
			r = FIPS_R_ERROR_RETRIEVING_NONCE;
			goto end;
			}

		}
	else
@@ -140,7 +177,10 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx,
				dctx->entropy, entlen,
				dctx->nonce, noncelen,
				pers, perslen))
		{
		r = FIPS_R_ERROR_INSTANTIATING_DRBG;
		goto end;
		}


	dctx->status = DRBG_STATUS_READY;
@@ -156,6 +196,9 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx,
	if (dctx->status == DRBG_STATUS_READY)
		return 1;

	if (r && !(dctx->flags & DRBG_FLAG_TEST))
		FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, r);

	return 0;

	}
@@ -164,19 +207,28 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx,
			const unsigned char *adin, size_t adinlen)
	{
	size_t entlen;
	int r = 0;

#if 0
	FIPSerr(FIPS_F_FIPS_DRBG_RESEED, FIPS_R_NOT_INSTANTIATED);
	FIPSerr(FIPS_F_FIPS_DRBG_RESEED, FIPS_R_ADDITIONAL_INPUT_TOO_LONG);
#endif
	if (dctx->status != DRBG_STATUS_READY
		&& dctx->status != DRBG_STATUS_RESEED)
		{
		/* error */
		return 0;
		if (dctx->status == DRBG_STATUS_ERROR)
			r = FIPS_R_IN_ERROR_STATE;
		else if(dctx->status == DRBG_STATUS_UNINITIALISED)
			r = FIPS_R_NOT_INSTANTIATED;
		goto end;
		}

	if (!adin)
		adinlen = 0;
	else if (adinlen > dctx->max_adin)
		{
		/* error */
		return 0;
		r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG;
		goto end;
		}

	dctx->status = DRBG_STATUS_ERROR;
@@ -185,7 +237,10 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx,
				dctx->min_entropy, dctx->max_entropy);

	if (entlen < dctx->min_entropy || entlen > dctx->max_entropy)
		{
		r = FIPS_R_ERROR_RETRIEVING_ENTROPY;
		goto end;
		}

	if (!dctx->reseed(dctx, dctx->entropy, entlen, adin, adinlen))
		goto end;
@@ -194,8 +249,13 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx,
	dctx->reseed_counter = 1;
	end:
	OPENSSL_cleanse(dctx->entropy, sizeof(dctx->entropy));

	if (dctx->status == DRBG_STATUS_READY)
		return 1;

	if (r && !(dctx->flags & DRBG_FLAG_TEST))
		FIPSerr(FIPS_F_FIPS_DRBG_RESEED, r);

	return 0;
	}

@@ -204,34 +264,49 @@ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
			int prediction_resistance,
			const unsigned char *adin, size_t adinlen)
	{
	int r = 0;
	if (outlen > dctx->max_request)
		{
		/* Too large */
		r = FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG;
		return 0;
		}
	if (dctx->status == DRBG_STATUS_RESEED || prediction_resistance)
		{
		if (!FIPS_drbg_reseed(dctx, adin, adinlen))
			return 0;
			{
			r = FIPS_R_RESEED_ERROR;
			goto end;
			}
		adin = NULL;
		adinlen = 0;
		}
	if (dctx->status != DRBG_STATUS_READY)
		{
		/* Bad error */
		return 0;
		if (dctx->status == DRBG_STATUS_ERROR)
			r = FIPS_R_IN_ERROR_STATE;
		else if(dctx->status == DRBG_STATUS_UNINITIALISED)
			r = FIPS_R_NOT_INSTANTIATED;
		goto end;
		}
	if (!dctx->generate(dctx, out, outlen, adin, adinlen))
		{
		/* Bad error */
		r = FIPS_R_GENERATE_ERROR;
		dctx->status = DRBG_STATUS_ERROR;
		return 0;
		goto end;
		}
	if (dctx->reseed_counter > dctx->reseed_interval)
		dctx->status = DRBG_STATUS_RESEED;
	else
		dctx->reseed_counter++;

	end:
	if (r)
		{
		if (!(dctx->flags & DRBG_FLAG_TEST))
			FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r);
		return 0;
		}

	return 1;
	}