Example #1
0
int fips_check_dsa_prng(DSA *dsa, size_t L, size_t N)
	{
	int strength;
	if (!FIPS_mode())
		return 1;

	if (dsa->flags & (DSA_FLAG_NON_FIPS_ALLOW|DSA_FLAG_FIPS_CHECKED))
		return 1;

	if (!L || !N)
		{
		L = BN_num_bits(dsa->p);
		N = BN_num_bits(dsa->q);
		}
	if (!dsa2_valid_parameters(L, N))
		{
		FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG, FIPS_R_INVALID_PARAMETERS);
		return 0;
		}

	strength = fips_ffc_strength(L, N);

	if (!strength)
		{
	    	FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG,FIPS_R_KEY_TOO_SHORT);
		return 0;
		}

	if (FIPS_rand_strength() >= strength)
		return 1;

	FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW);
	return 0;

	}
int FIPS_selftest_aes()
    {
    int n;

    /* Encrypt and check against known ciphertext */
    for(n=0 ; n < 1 ; ++n)
	{
	AES_KEY key;
	unsigned char buf[16];

	AES_set_encrypt_key(tests[n].key,128,&key);
	AES_encrypt(tests[n].plaintext,buf,&key);
	if(memcmp(buf,tests[n].ciphertext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}
    /* Decrypt and check against known plaintext */
    for(n=0 ; n < 1 ; ++n)
	{
	AES_KEY key;
	unsigned char buf[16];

	AES_set_decrypt_key(tests[n].key,128,&key);
	AES_decrypt(tests[n].ciphertext,buf,&key);
	if(memcmp(buf,tests[n].plaintext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}
    return 1;
    }
int FIPS_check_incore_fingerprint(void)
    {
    unsigned char sig[EVP_MAX_MD_SIZE];
    unsigned int len;
    int rv = 0;
#if defined(__sgi) && (defined(__mips) || defined(mips))
    extern int __dso_displacement[];
#else
    extern int OPENSSL_NONPIC_relocated;
#endif

    if (!fips_post_started(FIPS_TEST_INTEGRITY, 0, NULL))
	return 1;

    if (FIPS_text_start()==NULL)
	{
	FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM);
	goto err;
	}

    len=FIPS_incore_fingerprint(sig,sizeof(sig));

    if (len!=sizeof(FIPS_signature) ||
	memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
	{
	if (FIPS_signature>=FIPS_rodata_start && FIPS_signature<FIPS_rodata_end)
	    FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING);
#if defined(__sgi) && (defined(__mips) || defined(mips))
	else if (__dso_displacement!=NULL)
#else
	else if (OPENSSL_NONPIC_relocated)
#endif
	    FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED);
	else
	    FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
#ifdef OPENSSL_FIPS_DEBUGGER
    	rv = 1;
#endif
	goto err;
	}
    rv = 1;
    err:
    if (rv == 0)
    	fips_post_failed(FIPS_TEST_INTEGRITY, 0, NULL);
    else
	if (!fips_post_success(FIPS_TEST_INTEGRITY, 0, NULL))
		return 0;
    return rv;
    }
Example #4
0
int FIPS_cipher_ctx_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
	int ret;
	if (FIPS_selftest_failed())
		{
		FIPSerr(FIPS_F_FIPS_CIPHER_CTX_CTRL, FIPS_R_SELFTEST_FAILED);
		return 0;
		}
	if(!ctx->cipher) {
		EVPerr(EVP_F_FIPS_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
		return 0;
	}

	if(!ctx->cipher->ctrl) {
		EVPerr(EVP_F_FIPS_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
		return 0;
	}

	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
	if(ret == -1) {
		EVPerr(EVP_F_FIPS_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
		return 0;
	}
	return ret;
}
int FIPS_selftest_des()
{
    int n, ret = 0;
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
    for (n = 0; n < 2; ++n) {
        if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
                              tests2[n].key, NULL,
                              tests2[n].plaintext, tests2[n].ciphertext, 8))
            goto err;
    }

    /* Encrypt/decrypt with 3DES and compare to known answers */
    for (n = 0; n < 2; ++n) {
        if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
                              tests3[n].key, NULL,
                              tests3[n].plaintext, tests3[n].ciphertext, 8))
            goto err;
    }
    ret = 1;
 err:
    EVP_CIPHER_CTX_cleanup(&ctx);
    if (ret == 0)
        FIPSerr(FIPS_F_FIPS_SELFTEST_DES, FIPS_R_SELFTEST_FAILED);

    return ret;
}
Example #6
0
void FIPS_rand_add(const void *buf, int num, double entropy)
{
    if (!fips_approved_rand_meth && FIPS_module_mode()) {
        FIPSerr(FIPS_F_FIPS_RAND_ADD, FIPS_R_NON_FIPS_METHOD);
        return;
    }
    if (fips_rand_meth && fips_rand_meth->add)
        fips_rand_meth->add(buf, num, entropy);
}
int FIPS_selftest_rng()
	{
	FIPS_rand_reset();
	if (!FIPS_rand_test_mode())
		{
		FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
		return 0;
		}
	if (!fips_rand_test(aes_128_key,aes_128_tv)
		|| !fips_rand_test(aes_192_key, aes_192_tv)
		|| !fips_rand_test(aes_256_key, aes_256_tv))
		{
		FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
		return 0;
		}
	FIPS_rand_reset();
	return 1;
	}
Example #8
0
int fips_check_rsa(RSA *rsa)
	{
	const unsigned char tbs[] = "RSA Pairwise Check Data";
	unsigned char *ctbuf = NULL, *ptbuf = NULL;
	int len, ret = 0;
	EVP_PKEY pk;
    	pk.type = EVP_PKEY_RSA;
    	pk.pkey.rsa = rsa;

	/* Perform pairwise consistency signature test */
	if (!fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
			NULL, 0, NULL, RSA_PKCS1_PADDING, NULL)
		|| !fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
			NULL, 0, NULL, RSA_X931_PADDING, NULL)
		|| !fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
			NULL, 0, NULL, RSA_PKCS1_PSS_PADDING, NULL))
		goto err;
	/* Now perform pairwise consistency encrypt/decrypt test */
	ctbuf = OPENSSL_malloc(RSA_size(rsa));
	if (!ctbuf)
		goto err;

	len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING);
	if (len <= 0)
		goto err;
	/* Check ciphertext doesn't match plaintext */
	if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len))
		goto err;
	ptbuf = OPENSSL_malloc(RSA_size(rsa));

	if (!ptbuf)
		goto err;
	len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING);
	if (len != (sizeof(tbs) - 1))
		goto err;
	if (memcmp(ptbuf, tbs, len))
		goto err;

	ret = 1;

	if (!ptbuf)
		goto err;
	
	err:
	if (ret == 0)
		{
		fips_set_selftest_fail();
		FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
		}

	if (ctbuf)
		OPENSSL_free(ctbuf);
	if (ptbuf)
		OPENSSL_free(ptbuf);

	return ret;
	}
Example #9
0
int FIPS_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
			const unsigned char *in, unsigned int inl)
	{
	if (FIPS_selftest_failed())
		{
		FIPSerr(FIPS_F_FIPS_CIPHER, FIPS_R_SELFTEST_FAILED);
		return -1;
		}
	return ctx->cipher->do_cipher(ctx,out,in,inl);
	}
Example #10
0
int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num)
{
    if (!fips_approved_rand_meth && FIPS_module_mode()) {
        FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD);
        return 0;
    }
    if (fips_rand_meth && fips_rand_meth->seed)
        fips_rand_meth->seed(buf, num);
    return 1;
}
Example #11
0
int FIPS_rand_status(void)
{
    if (!fips_approved_rand_meth && FIPS_module_mode()) {
        FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD);
        return 0;
    }
    if (fips_rand_meth && fips_rand_meth->status)
        return fips_rand_meth->status();
    return 0;
}
Example #12
0
int FIPS_rand_pseudo_bytes(unsigned char *buf, int num)
{
    if (!fips_approved_rand_meth && FIPS_module_mode()) {
        FIPSerr(FIPS_F_FIPS_RAND_PSEUDO_BYTES, FIPS_R_NON_FIPS_METHOD);
        return 0;
    }
    if (fips_rand_meth && fips_rand_meth->pseudorand)
        return fips_rand_meth->pseudorand(buf, num);
    return -1;
}
Example #13
0
int FIPS_rand_bytes(unsigned char *buf, FIPS_RAND_SIZE_T num)
{
    if (!fips_approved_rand_meth && FIPS_module_mode()) {
        FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD);
        return 0;
    }
    if (fips_rand_meth && fips_rand_meth->bytes)
        return fips_rand_meth->bytes(buf, num);
    return 0;
}
Example #14
0
int fips_check_ec_prng(EC_KEY *ec)
	{
	int bits, strength;
	if (!FIPS_module_mode())
		return 1;

	if (ec->flags & (EC_FLAG_NON_FIPS_ALLOW|EC_FLAG_FIPS_CHECKED))
		return 1;

	if (!ec->group)
		return 1;

	bits = BN_num_bits(&ec->group->order);

	if (bits < 160)
		{
	    	FIPSerr(FIPS_F_FIPS_CHECK_EC_PRNG,FIPS_R_KEY_TOO_SHORT);
		return 0;
		}
	/* Comparable algorithm strengths: from SP800-57 table 2 */
	if (bits >= 512)
		strength = 256;
	else if (bits >= 384)
		strength = 192;
	else if (bits >= 256)
		strength = 128;
	else if (bits >= 224)
		strength = 112;
	else
		strength = 80;


	if (FIPS_rand_strength() >= strength)
		return 1;

	FIPSerr(FIPS_F_FIPS_CHECK_EC_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW);
	return 0;

	}
static int fips_check_dsa(DSA *dsa)
{
    EVP_PKEY pk;
    unsigned char tbs[] = "DSA Pairwise Check Data";
    pk.type = EVP_PKEY_DSA;
    pk.pkey.dsa = dsa;

    if (!fips_pkey_signature_test(&pk, tbs, -1, NULL, 0, EVP_dss1(), 0, NULL)) {
        FIPSerr(FIPS_F_FIPS_CHECK_DSA, FIPS_R_PAIRWISE_TEST_FAILED);
        fips_set_selftest_fail();
        return 0;
    }
    return 1;
}
Example #16
0
static int fips_check_dsa(DSA *dsa)
    {
    static const unsigned char str1[]="12345678901234567890";
    unsigned char sig[256];
    unsigned int siglen;

    DSA_sign(0, str1, 20, sig, &siglen, dsa);
    if(DSA_verify(0, str1, 20, sig, siglen, dsa) != 1)
	{
	FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
	return 0;
	}
    return 1;
    }
Example #17
0
int FIPS_dsa_check(struct dsa_st *dsa)
    {
    if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign
       || dsa->meth->dsa_sign_setup != dsa_sign_setup
       || dsa->meth->dsa_mod_exp != dsa_mod_exp
       || dsa->meth->bn_mod_exp != dsa_bn_mod_exp
       || dsa->meth->init != dsa_init
       || dsa->meth->finish != dsa_finish)
	{
	FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD);
	return 0;
	}
    return 1;
    }
Example #18
0
int fips_check_rsa_prng(RSA *rsa, int bits)
	{
	int strength;
	if (!FIPS_module_mode())
		return 1;

	if (rsa->flags & (RSA_FLAG_NON_FIPS_ALLOW|RSA_FLAG_CHECKED))
		return 1;

	if (bits == 0)
		bits = BN_num_bits(rsa->n);

	/* Should never happen */
	if (bits < 1024)
		{
	    	FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_KEY_TOO_SHORT);
		return 0;
		}
	/* From SP800-57 */
	if (bits < 2048)
		strength = 80;
	else if (bits < 3072)
		strength = 112;
	else if (bits < 7680)
		strength = 128;
	else if (bits < 15360)
		strength = 192;
	else 
		strength = 256;

	if (FIPS_rand_strength() >= strength)
		return 1;

	FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW);
	return 0;
	}
Example #19
0
static int fips_check_ec(EC_KEY *key)
	{
	EVP_PKEY pk;
	unsigned char tbs[] = "ECDSA Pairwise Check Data";
    	pk.type = EVP_PKEY_EC;
    	pk.pkey.ec = key;

	if (!fips_pkey_signature_test(FIPS_TEST_PAIRWISE,
					&pk, tbs, 0, NULL, 0, NULL, 0, NULL))
		{
		FIPSerr(FIPS_F_FIPS_CHECK_EC,FIPS_R_PAIRWISE_TEST_FAILED);
		fips_set_selftest_fail();
		return 0;
		}
	return 1;
	}
int FIPS_selftest_cmac()
{
    size_t n, outlen;
    unsigned char out[32];
    const EVP_CIPHER *cipher;
    CMAC_CTX *ctx = CMAC_CTX_new();
    const CMAC_KAT *t;
    int rv = 1;

    for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) {
        cipher = FIPS_get_cipherbynid(t->nid);
        if (!cipher) {
            rv = -1;
            goto err;
        }
        if (!CMAC_Init(ctx, t->key, t->keysize / 8, cipher, 0)) {
            rv = -1;
            goto err;
        }
        if (!CMAC_Update(ctx, t->msg, t->msgsize / 8)) {
            rv = -1;
            goto err;
        }

        if (!CMAC_Final(ctx, out, &outlen)) {
            rv = -1;
            goto err;
        }
        CMAC_CTX_cleanup(ctx);

        if (outlen < t->macsize / 8 || memcmp(out, t->mac, t->macsize / 8)) {
            rv = 0;
        }
    }

 err:
    CMAC_CTX_free(ctx);

    if (rv == -1) {
        rv = 0;
    }
    if (!rv)
        FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC, FIPS_R_SELFTEST_FAILED);

    return rv;
}
int FIPS_selftest_sha1()
    {
    int n;

    for(n=0 ; n<sizeof(test)/sizeof(test[0]) ; ++n)
	{
	unsigned char md[SHA_DIGEST_LENGTH];

	EVP_Digest(test[n],strlen(test[n]),md, NULL, EVP_sha1(), NULL);
	if(memcmp(md,ret[n],sizeof md))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}
    return 1;
    }
Example #22
0
int FIPS_rand_set_method(const RAND_METHOD *meth)
{
    if (!fips_rand_bits) {
        if (meth == FIPS_drbg_method())
            fips_approved_rand_meth = 1;
        else if (meth == FIPS_x931_method())
            fips_approved_rand_meth = 2;
        else {
            fips_approved_rand_meth = 0;
            if (FIPS_module_mode()) {
                FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD, FIPS_R_NON_FIPS_METHOD);
                return 0;
            }
        }
    }
    fips_rand_meth = meth;
    return 1;
}
int FIPS_selftest_hmac()
    {
    int n;
    unsigned int    outlen;
    unsigned char   out[EVP_MAX_MD_SIZE];
    const EVP_MD   *md;
    const HMAC_KAT *t;

    for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++)
	{
	md = (*t->alg)();
	HMAC(md,t->key,strlen(t->key),
		(const unsigned char *)t->iv,strlen(t->iv),
		out,&outlen);

	if(memcmp(out,t->kaval,outlen))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}
    return 1;
    }
Example #24
0
int FIPS_rsa_sign_digest(RSA *rsa, const unsigned char *md, int md_len,
			const EVP_MD *mhash, int rsa_pad_mode, int saltlen,
			const EVP_MD *mgf1Hash,
			unsigned char *sigret, unsigned int *siglen)
	{
	int i=0,j,ret=0;
	unsigned int dlen;
	const unsigned char *der;
	int md_type;
	/* Largest DigestInfo: 19 (max encoding) + max MD */
	unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];

	if (FIPS_selftest_failed())
		{
		FIPSerr(FIPS_F_FIPS_RSA_SIGN_DIGEST, FIPS_R_SELFTEST_FAILED);
		return 0;
		}
	if (!mhash && rsa_pad_mode == RSA_PKCS1_PADDING)
		md_type = saltlen;
	else
		md_type = M_EVP_MD_type(mhash);

	if (rsa_pad_mode == RSA_X931_PADDING)
		{
		int hash_id;
		memcpy(tmpdinfo, md, md_len);
		hash_id = RSA_X931_hash_id(md_type);
		if (hash_id == -1)
			{
			RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
			return 0;
			}
		tmpdinfo[md_len] = (unsigned char)hash_id;
		i = md_len + 1;
		}
	else if (rsa_pad_mode == RSA_PKCS1_PADDING)
		{

		der = fips_digestinfo_encoding(md_type, &dlen);
		
		if (!der)
			{
			RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
			return 0;
			}
		memcpy(tmpdinfo, der, dlen);
		memcpy(tmpdinfo + dlen, md, md_len);

		i = dlen + md_len;

		}
	else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
		{
		unsigned char *sbuf;
		i = RSA_size(rsa);
		sbuf = OPENSSL_malloc(RSA_size(rsa));
		if (!sbuf)
			{
			RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,ERR_R_MALLOC_FAILURE);
			goto psserr;
			}
		if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, sbuf, md, mhash, 
							mgf1Hash, saltlen))
			goto psserr;
		j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING);
		if (j > 0)
			{
			ret=1;
			*siglen=j;
			}
		psserr:
		OPENSSL_cleanse(sbuf, i);
		OPENSSL_free(sbuf);
		return ret;
		}

	j=RSA_size(rsa);
	if (i > (j-RSA_PKCS1_PADDING_SIZE))
		{
		RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
		goto done;
		}
	/* NB: call underlying method directly to avoid FIPS blocking */
	j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode);
	if (j > 0)
		{
		ret=1;
		*siglen=j;
		}

	done:
	OPENSSL_cleanse(tmpdinfo,i);
	return ret;
	}
Example #25
0
int FIPS_rsa_verify_digest(RSA *rsa, const unsigned char *dig, int diglen,
			const EVP_MD *mhash, int rsa_pad_mode, int saltlen,
			const EVP_MD *mgf1Hash,
			const unsigned char *sigbuf, unsigned int siglen)
	{
	int i,ret=0;
	unsigned int dlen;
	unsigned char *s;
	const unsigned char *der;
	int md_type;
	int rsa_dec_pad_mode;

	if (FIPS_selftest_failed())
		{
		FIPSerr(FIPS_F_FIPS_RSA_VERIFY_DIGEST, FIPS_R_SELFTEST_FAILED);
		return 0;
		}

	if (siglen != (unsigned int)RSA_size(rsa))
		{
		RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_WRONG_SIGNATURE_LENGTH);
		return(0);
		}

	if (!mhash && rsa_pad_mode == RSA_PKCS1_PADDING)
		md_type = saltlen;
	else
		md_type = M_EVP_MD_type(mhash);

	s= OPENSSL_malloc((unsigned int)siglen);
	if (s == NULL)
		{
		RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
		rsa_dec_pad_mode = RSA_NO_PADDING;
	else
		rsa_dec_pad_mode = rsa_pad_mode;

	/* NB: call underlying method directly to avoid FIPS blocking */
	i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_dec_pad_mode);

	if (i <= 0) goto err;

	if (rsa_pad_mode == RSA_X931_PADDING)
		{
		int hash_id;
		if (i != (int)(diglen + 1))
			{
			RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
			goto err;
			}
		hash_id = RSA_X931_hash_id(md_type);
		if (hash_id == -1)
			{
			RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
			goto err;
			}
		if (s[diglen] != (unsigned char)hash_id)
			{
			RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
			goto err;
			}
		if (memcmp(s, dig, diglen))
			{
			RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
			goto err;
			}
		ret = 1;
		}
	else if (rsa_pad_mode == RSA_PKCS1_PADDING)
		{

		der = fips_digestinfo_encoding(md_type, &dlen);
		
		if (!der)
			{
			RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
			return(0);
			}

		/* Compare, DigestInfo length, DigestInfo header and finally
		 * digest value itself
		 */

		/* If length mismatch try alternate encoding */
		if (i != (int)(dlen + diglen))
			der = fips_digestinfo_nn_encoding(md_type, &dlen);

		if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
			|| memcmp(s + dlen, dig, diglen))
			{
			RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
			goto err;
			}
		ret = 1;

		}
	else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
		{
		ret = RSA_verify_PKCS1_PSS_mgf1(rsa, dig, mhash, mgf1Hash,
						s, saltlen);
		if (ret < 0)
			ret = 0;
		}
err:
	if (s != NULL)
		{
		OPENSSL_cleanse(s, siglen);
		OPENSSL_free(s);
		}
	return(ret);
	}
/* The purpose of this is to ensure the error code exists and the function
 * name is to keep the error checking script quiet
 */
void hash_final(void)
	{
	FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD);
	}
int FIPS_module_mode_set(int onoff, const char *auth)
    {
    int ret = 0;

    fips_w_lock();
    fips_started = 1;
    fips_set_owning_thread();

    if(onoff)
	{

	fips_selftest_fail = 0;
    	if (!fips_check_auth(auth))
	    {
	    fips_auth_fail = 1;
	    fips_selftest_fail = 1;
	    FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_AUTHENTICATION_FAILURE);
	    return 0;
	    }

	/* Don't go into FIPS mode twice, just so we can do automagic
	   seeding */
	if(FIPS_module_mode())
	    {
	    FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET);
	    fips_selftest_fail = 1;
	    ret = 0;
	    goto end;
	    }

#ifdef OPENSSL_IA32_SSE2
	{
	extern unsigned int OPENSSL_ia32cap_P[2];
	if ((OPENSSL_ia32cap_P[0] & (1<<25|1<<26)) != (1<<25|1<<26))
	    {
	    FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM);
	    fips_selftest_fail = 1;
	    ret = 0;
	    goto end;
	    }
	OPENSSL_ia32cap_P[0] |= (1<<28);	/* set "shared cache"	*/
	OPENSSL_ia32cap_P[1] &= ~(1<<(60-32));	/* clear AVX		*/
	}
#endif

	if(fips_signature_witness() != FIPS_signature)
	    {
	    FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE);
	    fips_selftest_fail = 1;
	    ret = 0;
	    goto end;
	    }

	if(FIPS_selftest())
	    fips_set_mode(onoff);
	else
	    {
	    fips_selftest_fail = 1;
	    ret = 0;
	    goto end;
	    }
	ret = 1;
	goto end;
	}
    fips_set_mode(0);
    fips_selftest_fail = 0;
    ret = 1;
end:
    fips_clear_owning_thread();
    fips_w_unlock();
    return ret;
    }
Example #28
0
/* This implementation is based on the following primitives in the IEEE 1363 standard:
 *  - ECKAS-DH1
 *  - ECSVDP-DH
 * Finally an optional KDF is applied.
 */
static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
	EC_KEY *ecdh,
	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
	{
	BN_CTX *ctx;
	EC_POINT *tmp=NULL;
	BIGNUM *x=NULL, *y=NULL;
	const BIGNUM *priv_key;
	const EC_GROUP* group;
	int ret= -1;
	size_t buflen, len;
	unsigned char *buf=NULL;

#ifdef OPENSSL_FIPS
	if(FIPS_selftest_failed())
		{
		FIPSerr(FIPS_F_ECDH_COMPUTE_KEY,FIPS_R_FIPS_SELFTEST_FAILED);
		return -1;
		}
#endif

	if (outlen > INT_MAX)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
		return -1;
		}

	if ((ctx = BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	
	priv_key = EC_KEY_get0_private_key(ecdh);
	if (priv_key == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
		goto err;
		}

	group = EC_KEY_get0_group(ecdh);
	if ((tmp=EC_POINT_new(group)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) 
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
		goto err;
		}
		
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#ifndef OPENSSL_NO_EC2M
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#endif

	buflen = (EC_GROUP_get_degree(group) + 7)/8;
	len = BN_num_bytes(x);
	if (len > buflen)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
		goto err;
		}
	if ((buf = OPENSSL_malloc(buflen)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	
	memset(buf, 0, buflen - len);
	if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	if (KDF != 0)
		{
		if (KDF(buf, buflen, out, &outlen) == NULL)
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
			goto err;
			}
		ret = outlen;
		}
	else
		{
		/* no KDF, just copy as much as we can */
		if (outlen > buflen)
			outlen = buflen;
		memcpy(out, buf, outlen);
		ret = outlen;
		}
	
err:
	if (tmp) EC_POINT_free(tmp);
	if (ctx) BN_CTX_end(ctx);
	if (ctx) BN_CTX_free(ctx);
	if (buf) OPENSSL_free(buf);
	return(ret);
	}
Example #29
0
int fips_pkey_signature_test(int id, EVP_PKEY *pkey,
			const unsigned char *tbs, size_t tbslen,
			const unsigned char *kat, size_t katlen,
			const EVP_MD *digest, int pad_mode,
			const char *fail_str)
	{	
	int subid;
	void *ex = NULL;
	int ret = 0;
	unsigned char *sig = NULL;
	unsigned int siglen;
	static const unsigned char str1[]="12345678901234567890";
	DSA_SIG *dsig = NULL;
	ECDSA_SIG *esig = NULL;
	EVP_MD_CTX mctx;
	FIPS_md_ctx_init(&mctx);

	if (tbs == NULL)
		tbs = str1;

	if (tbslen == 0)
		tbslen = strlen((char *)tbs);

	if (digest == NULL)
		digest = EVP_sha256();

	subid = M_EVP_MD_type(digest);


	if (!fips_post_started(id, subid, pkey))
		return 1;

	if (!pkey || pkey->type == EVP_PKEY_RSA)
		{
		size_t sigsize;
		if (!pkey)
			sigsize = EVP_MAX_MD_SIZE;
		else
			sigsize = RSA_size(pkey->pkey.rsa);

		sig = OPENSSL_malloc(sigsize);
		if (!sig)
			{
			FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE);
			goto error;
			}
		}

	if (!FIPS_digestinit(&mctx, digest))
		goto error;
	if (!FIPS_digestupdate(&mctx, tbs, tbslen))
		goto error;

	if (!fips_post_corrupt(id, subid, pkey))
		{
		if (!FIPS_digestupdate(&mctx, tbs, 1))
			goto error;
		}

	if (pkey == NULL)
		{
		if (!FIPS_digestfinal(&mctx, sig, &siglen))
			goto error;
		}
	else if (pkey->type == EVP_PKEY_RSA)
		{
		if (!FIPS_rsa_sign_ctx(pkey->pkey.rsa, &mctx,
					pad_mode, 0, NULL, sig, &siglen))
			goto error;
		}
	else if (pkey->type == EVP_PKEY_DSA)
		{
		dsig = FIPS_dsa_sign_ctx(pkey->pkey.dsa, &mctx);
		if (!dsig)
			goto error;
		}
	else if (pkey->type == EVP_PKEY_EC)
		{
		esig = FIPS_ecdsa_sign_ctx(pkey->pkey.ec, &mctx);
		if (!esig)
			goto error;
		}

	if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
		goto error;
#if 0
	{
	/* Debug code to print out self test KAT discrepancies */
	unsigned int i;
	fprintf(stderr, "%s=", fail_str);
	for (i = 0; i < siglen; i++)
			fprintf(stderr, "%02X", sig[i]);
	fprintf(stderr, "\n");
	goto error;
	}
#endif
	/* If just digest test we've finished */
	if (pkey == NULL)
		{
		ret = 1;
		/* Well actually sucess as we've set ret to 1 */
		goto error;
		}
	if (!FIPS_digestinit(&mctx, digest))
		goto error;
	if (!FIPS_digestupdate(&mctx, tbs, tbslen))
		goto error;
	if (pkey->type == EVP_PKEY_RSA)
		{
		ret = FIPS_rsa_verify_ctx(pkey->pkey.rsa, &mctx,
						pad_mode, 0, NULL, sig, siglen);
		}
	else if (pkey->type == EVP_PKEY_DSA)
		{
		ret = FIPS_dsa_verify_ctx(pkey->pkey.dsa, &mctx, dsig);
		}
	else if (pkey->type == EVP_PKEY_EC)
		{
		ret = FIPS_ecdsa_verify_ctx(pkey->pkey.ec, &mctx, esig);
		}

	error:
	if (dsig != NULL)
		FIPS_dsa_sig_free(dsig);
	if (esig != NULL)
		FIPS_ecdsa_sig_free(esig);
	if (sig)
		OPENSSL_free(sig);
	FIPS_md_ctx_cleanup(&mctx);
	if (ret != 1)
		{
		FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
		if (fail_str)
			FIPS_add_error_data(2, "Type=", fail_str);
		fips_post_failed(id, subid, ex);
		return 0;
		}
	return fips_post_success(id, subid, pkey);
	}
Example #30
0
static int ssleay_rand_bytes(unsigned char *buf, int num)
	{
	static volatile int stirred_pool = 0;
	int i,j,k,st_num,st_idx;
	int num_ceil;
	int ok;
	long md_c[2];
	unsigned char local_md[MD_DIGEST_LENGTH];
	EVP_MD_CTX m;
#ifndef GETPID_IS_MEANINGLESS
	pid_t curr_pid = getpid();
#endif
	int do_stir_pool = 0;

#ifdef OPENSSL_FIPS
	if(FIPS_mode())
	    {
	    FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD);
	    return 0;
	    }
#endif

#ifdef PREDICT
	if (rand_predictable)
		{
		static unsigned char val=0;

		for (i=0; i<num; i++)
			buf[i]=val++;
		return(1);
		}
#endif

	if (num <= 0)
		return 1;

	EVP_MD_CTX_init(&m);
	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);

	/*
	 * (Based on the rand(3) manpage:)
	 *
	 * For each group of 10 bytes (or less), we do the following:
	 *
	 * Input into the hash function the local 'md' (which is initialized from
	 * the global 'md' before any bytes are generated), the bytes that are to
	 * be overwritten by the random bytes, and bytes from the 'state'
	 * (incrementing looping index). From this digest output (which is kept
	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
	 * bottom 10 bytes are xored into the 'state'.
	 * 
	 * Finally, after we have finished 'num' random bytes for the
	 * caller, 'count' (which is incremented) and the local and global 'md'
	 * are fed into the hash function and the results are kept in the
	 * global 'md'.
	 */

	CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
	locking_thread = CRYPTO_thread_id();
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
	crypto_lock_rand = 1;

	if (!initialized)
		{
		RAND_poll();
		initialized = 1;
		}
	
	if (!stirred_pool)
		do_stir_pool = 1;
	
	ok = (entropy >= ENTROPY_NEEDED);
	if (!ok)
		{
		/* If the PRNG state is not yet unpredictable, then seeing
		 * the PRNG output may help attackers to determine the new
		 * state; thus we have to decrease the entropy estimate.
		 * Once we've had enough initial seeding we don't bother to
		 * adjust the entropy count, though, because we're not ambitious
		 * to provide *information-theoretic* randomness.
		 *
		 * NOTE: This approach fails if the program forks before
		 * we have enough entropy. Entropy should be collected
		 * in a separate input pool and be transferred to the
		 * output pool only when the entropy limit has been reached.
		 */
		entropy -= num;
		if (entropy < 0)
			entropy = 0;
		}

	if (do_stir_pool)
		{
		/* In the output function only half of 'md' remains secret,
		 * so we better make sure that the required entropy gets
		 * 'evenly distributed' through 'state', our randomness pool.
		 * The input function (ssleay_rand_add) chains all of 'md',
		 * which makes it more suitable for this purpose.
		 */

		int n = STATE_SIZE; /* so that the complete pool gets accessed */
		while (n > 0)
			{
#if MD_DIGEST_LENGTH > 20
# error "Please adjust DUMMY_SEED."
#endif
#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
			/* Note that the seed does not matter, it's just that
			 * ssleay_rand_add expects to have something to hash. */
			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
			n -= MD_DIGEST_LENGTH;
			}
		if (ok)
			stirred_pool = 1;
		}

	st_idx=state_index;
	st_num=state_num;
	md_c[0] = md_count[0];
	md_c[1] = md_count[1];
	memcpy(local_md, md, sizeof md);

	state_index+=num_ceil;
	if (state_index > state_num)
		state_index %= state_num;

	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
	 * are now ours (but other threads may use them too) */

	md_count[0] += 1;

	/* before unlocking, we must clear 'crypto_lock_rand' */
	crypto_lock_rand = 0;
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	while (num > 0)
		{
		/* num_ceil -= MD_DIGEST_LENGTH/2 */
		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
		num-=j;
		MD_Init(&m);
#ifndef GETPID_IS_MEANINGLESS
		if (curr_pid) /* just in the first iteration to save time */
			{
			MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
			curr_pid = 0;
			}
#endif
		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
#ifndef PURIFY
		MD_Update(&m,buf,j); /* purify complains */
#endif
		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
		if (k > 0)
			{
			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
			MD_Update(&m,&(state[0]),k);
			}
		else
			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
		MD_Final(&m,local_md);

		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
			{
			state[st_idx++]^=local_md[i]; /* may compete with other threads */
			if (st_idx >= st_num)
				st_idx=0;
			if (i < j)
				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
			}
		}

	MD_Init(&m);
	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	MD_Update(&m,md,MD_DIGEST_LENGTH);
	MD_Final(&m,md);
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	EVP_MD_CTX_cleanup(&m);
	if (ok)
		return(1);
	else
		{
		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
			"http://www.openssl.org/support/faq.html");
		return(0);
		}
	}