⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fips_rsa_sign.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
字号:
/* fips_rsa_sign.c *//* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2007. *//* ==================================================================== * Copyright (c) 2007 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com).  This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */#include <string.h>#include <openssl/evp.h>#include <openssl/rsa.h>#include <openssl/err.h>#include <openssl/sha.h>#ifdef OPENSSL_FIPS/* FIPS versions of RSA_sign() and RSA_verify(). * These will only have to deal with SHA* signatures and by including * pregenerated encodings all ASN1 dependencies can be avoided *//* Standard encodings including NULL parameter */static const unsigned char sha1_bin[] = {  0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,  0x00, 0x04, 0x14};static const unsigned char sha224_bin[] = {  0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c};static const unsigned char sha256_bin[] = {  0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};static const unsigned char sha384_bin[] = {  0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};static const unsigned char sha512_bin[] = {  0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};/* Alternate encodings with absent parameters. We don't generate signature * using this format but do tolerate received signatures of this form. */static unsigned char sha1_nn_bin[] = {  0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,  0x14};static unsigned char sha224_nn_bin[] = {  0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x04, 0x04, 0x1c};static unsigned char sha256_nn_bin[] = {  0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x01, 0x04, 0x20};static unsigned char sha384_nn_bin[] = {  0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x02, 0x04, 0x30};static unsigned char sha512_nn_bin[] = {  0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,  0x04, 0x02, 0x03, 0x04, 0x40};static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)	{	switch (nid)		{		case NID_sha1:		*len = sizeof(sha1_bin);		return sha1_bin;		case NID_sha224:		*len = sizeof(sha224_bin);		return sha224_bin;		case NID_sha256:		*len = sizeof(sha256_bin);		return sha256_bin;		case NID_sha384:		*len = sizeof(sha384_bin);		return sha384_bin;		case NID_sha512:		*len = sizeof(sha512_bin);		return sha512_bin;		default:		return NULL;		}	}static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len)	{	switch (nid)		{		case NID_sha1:		*len = sizeof(sha1_nn_bin);		return sha1_nn_bin;		case NID_sha224:		*len = sizeof(sha224_nn_bin);		return sha224_nn_bin;		case NID_sha256:		*len = sizeof(sha256_nn_bin);		return sha256_nn_bin;		case NID_sha384:		*len = sizeof(sha384_nn_bin);		return sha384_nn_bin;		case NID_sha512:		*len = sizeof(sha512_nn_bin);		return sha512_nn_bin;		default:		return NULL;		}	}static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,	     unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv)	{	int i=0,j,ret=0;	unsigned int dlen;	const unsigned char *der;	unsigned int m_len;	int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;	int rsa_pad_mode = 0;	RSA *rsa = sv->key;	/* Largest DigestInfo: 19 (max encoding) + max MD */	unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];	unsigned char md[EVP_MAX_MD_SIZE + 1];        EVP_DigestFinal_ex(sv->mctx, md, &m_len);	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)		{		ret = rsa->meth->rsa_sign(type, md, m_len,			sigret, siglen, rsa);		goto done;		}	if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)		{		int hash_id;		memcpy(tmpdinfo, md, m_len);		hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));		if (hash_id == -1)			{			RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);			return 0;			}		tmpdinfo[m_len] = (unsigned char)hash_id;		i = m_len + 1;		rsa_pad_mode = RSA_X931_PADDING;		}	else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)		{		der = fips_digestinfo_encoding(type, &dlen);				if (!der)			{			RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);			return 0;			}		memcpy(tmpdinfo, der, dlen);		memcpy(tmpdinfo + dlen, md, m_len);		i = dlen + m_len;		rsa_pad_mode = RSA_PKCS1_PADDING;		}	else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)		{		unsigned char *sbuf;		int saltlen;		i = RSA_size(rsa);		sbuf = OPENSSL_malloc(RSA_size(rsa));		saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);		if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)			saltlen = -1;		else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)			saltlen = -2;		if (!sbuf)			{			RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE);			goto psserr;			}		if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md,					M_EVP_MD_CTX_md(sv->mctx), 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(md,m_len);		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,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);	OPENSSL_cleanse(md,m_len);	return ret;	}static int fips_rsa_verify(int dtype,		const unsigned char *x, unsigned int y,		unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)	{	int i,ret=0;	unsigned int dlen, diglen;	int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;	int rsa_pad_mode = 0;	unsigned char *s;	const unsigned char *der;	unsigned char dig[EVP_MAX_MD_SIZE];	RSA *rsa = sv->key;	if (siglen != (unsigned int)RSA_size(sv->key))		{		RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);		return(0);		}        EVP_DigestFinal_ex(sv->mctx, dig, &diglen);	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)		{		return rsa->meth->rsa_verify(dtype, dig, diglen,			sigbuf, siglen, rsa);		}	s= OPENSSL_malloc((unsigned int)siglen);	if (s == NULL)		{		RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE);		goto err;		}	if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)		rsa_pad_mode = RSA_X931_PADDING;	else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)		rsa_pad_mode = RSA_PKCS1_PADDING;	else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)		rsa_pad_mode = RSA_NO_PADDING;	/* NB: call underlying method directly to avoid FIPS blocking */	i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode);	if (i <= 0) goto err;	if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)		{		int hash_id;		if (i != (int)(diglen + 1))			{			RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);			goto err;			}		hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));		if (hash_id == -1)			{			RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);			goto err;			}		if (s[diglen] != (unsigned char)hash_id)			{			RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);			goto err;			}		if (memcmp(s, dig, diglen))			{			RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);			goto err;			}		ret = 1;		}	else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)		{		der = fips_digestinfo_encoding(dtype, &dlen);				if (!der)			{			RSAerr(RSA_F_FIPS_RSA_VERIFY,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(dtype, &dlen);		if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)			|| memcmp(s + dlen, dig, diglen))			{			RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);			goto err;			}		ret = 1;		}	else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)		{		int saltlen;		saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);		if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)			saltlen = -1;		else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)			saltlen = -2;		ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx),						s, saltlen);		if (ret < 0)			ret = 0;		}err:	if (s != NULL)		{		OPENSSL_cleanse(s, siglen);		OPENSSL_free(s);		}	return(ret);	}#define EVP_PKEY_RSA_fips_method \				(evp_sign_method *)fips_rsa_sign, \				(evp_verify_method *)fips_rsa_verify, \				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}static int init(EVP_MD_CTX *ctx)	{ return SHA1_Init(ctx->md_data); }static int update(EVP_MD_CTX *ctx,const void *data,size_t count)	{ return SHA1_Update(ctx->md_data,data,count); }static int final(EVP_MD_CTX *ctx,unsigned char *md)	{ return SHA1_Final(md,ctx->md_data); }static const EVP_MD sha1_md=	{	NID_sha1,	NID_sha1WithRSAEncryption,	SHA_DIGEST_LENGTH,	EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,	init,	update,	final,	NULL,	NULL,	EVP_PKEY_RSA_fips_method,	SHA_CBLOCK,	sizeof(EVP_MD *)+sizeof(SHA_CTX),	};const EVP_MD *EVP_sha1(void)	{	return(&sha1_md);	}static int init224(EVP_MD_CTX *ctx)	{ return SHA224_Init(ctx->md_data); }static int init256(EVP_MD_CTX *ctx)	{ return SHA256_Init(ctx->md_data); }/* * Even though there're separate SHA224_[Update|Final], we call * SHA256 functions even in SHA224 context. This is what happens * there anyway, so we can spare few CPU cycles:-) */static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)	{ return SHA256_Update(ctx->md_data,data,count); }static int final256(EVP_MD_CTX *ctx,unsigned char *md)	{ return SHA256_Final(md,ctx->md_data); }static const EVP_MD sha224_md=	{	NID_sha224,	NID_sha224WithRSAEncryption,	SHA224_DIGEST_LENGTH,	EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,	init224,	update256,	final256,	NULL,	NULL,	EVP_PKEY_RSA_fips_method,	SHA256_CBLOCK,	sizeof(EVP_MD *)+sizeof(SHA256_CTX),	};const EVP_MD *EVP_sha224(void)	{ return(&sha224_md); }static const EVP_MD sha256_md=	{	NID_sha256,	NID_sha256WithRSAEncryption,	SHA256_DIGEST_LENGTH,	EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,	init256,	update256,	final256,	NULL,	NULL,	EVP_PKEY_RSA_fips_method,	SHA256_CBLOCK,	sizeof(EVP_MD *)+sizeof(SHA256_CTX),	};const EVP_MD *EVP_sha256(void)	{ return(&sha256_md); }static int init384(EVP_MD_CTX *ctx)	{ return SHA384_Init(ctx->md_data); }static int init512(EVP_MD_CTX *ctx)	{ return SHA512_Init(ctx->md_data); }/* See comment in SHA224/256 section */static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)	{ return SHA512_Update(ctx->md_data,data,count); }static int final512(EVP_MD_CTX *ctx,unsigned char *md)	{ return SHA512_Final(md,ctx->md_data); }static const EVP_MD sha384_md=	{	NID_sha384,	NID_sha384WithRSAEncryption,	SHA384_DIGEST_LENGTH,	EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,	init384,	update512,	final512,	NULL,	NULL,	EVP_PKEY_RSA_fips_method,	SHA512_CBLOCK,	sizeof(EVP_MD *)+sizeof(SHA512_CTX),	};const EVP_MD *EVP_sha384(void)	{ return(&sha384_md); }static const EVP_MD sha512_md=	{	NID_sha512,	NID_sha512WithRSAEncryption,	SHA512_DIGEST_LENGTH,	EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,	init512,	update512,	final512,	NULL,	NULL,	EVP_PKEY_RSA_fips_method,	SHA512_CBLOCK,	sizeof(EVP_MD *)+sizeof(SHA512_CTX),	};const EVP_MD *EVP_sha512(void)	{ return(&sha512_md); }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -