os/ossrv/ssl/libcrypto/src/crypto/rsa/rsa_oaep.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/rsa/rsa_oaep.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,213 @@
     1.4 +/* crypto/rsa/rsa_oaep.c */
     1.5 +/* Written by Ulf Moeller. This software is distributed on an "AS IS"
     1.6 +   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
     1.7 +
     1.8 +/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
     1.9 +
    1.10 +/* See Victor Shoup, "OAEP reconsidered," Nov. 2000,
    1.11 + * <URL: http://www.shoup.net/papers/oaep.ps.Z>
    1.12 + * for problems with the security proof for the
    1.13 + * original OAEP scheme, which EME-OAEP is based on.
    1.14 + * 
    1.15 + * A new proof can be found in E. Fujisaki, T. Okamoto,
    1.16 + * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!",
    1.17 + * Dec. 2000, <URL: http://eprint.iacr.org/2000/061/>.
    1.18 + * The new proof has stronger requirements for the
    1.19 + * underlying permutation: "partial-one-wayness" instead
    1.20 + * of one-wayness.  For the RSA function, this is
    1.21 + * an equivalent notion.
    1.22 + */
    1.23 +
    1.24 +
    1.25 +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
    1.26 +#include <stdio.h>
    1.27 +#include "cryptlib.h"
    1.28 +#include <openssl/bn.h>
    1.29 +#include <openssl/rsa.h>
    1.30 +#include <openssl/evp.h>
    1.31 +#include <openssl/rand.h>
    1.32 +#include <openssl/sha.h>
    1.33 +
    1.34 +EXPORT_C int MGF1(unsigned char *mask, long len,
    1.35 +	const unsigned char *seed, long seedlen);
    1.36 +
    1.37 +EXPORT_C int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
    1.38 +	const unsigned char *from, int flen,
    1.39 +	const unsigned char *param, int plen)
    1.40 +	{
    1.41 +	int i, emlen = tlen - 1;
    1.42 +	unsigned char *db, *seed;
    1.43 +	unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
    1.44 +
    1.45 +	if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1)
    1.46 +		{
    1.47 +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
    1.48 +		   RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    1.49 +		return 0;
    1.50 +		}
    1.51 +
    1.52 +	if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
    1.53 +		{
    1.54 +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
    1.55 +		return 0;
    1.56 +		}
    1.57 +
    1.58 +	dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
    1.59 +	if (dbmask == NULL)
    1.60 +		{
    1.61 +		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
    1.62 +		return 0;
    1.63 +		}
    1.64 +
    1.65 +	to[0] = 0;
    1.66 +	seed = to + 1;
    1.67 +	db = to + SHA_DIGEST_LENGTH + 1;
    1.68 +
    1.69 +	EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL);
    1.70 +	memset(db + SHA_DIGEST_LENGTH, 0,
    1.71 +		emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
    1.72 +	db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
    1.73 +	memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
    1.74 +	if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
    1.75 +		return 0;
    1.76 +#ifdef PKCS_TESTVECT
    1.77 +	memcpy(seed,
    1.78 +	   "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
    1.79 +	   20);
    1.80 +#endif
    1.81 +
    1.82 +	MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
    1.83 +	for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
    1.84 +		db[i] ^= dbmask[i];
    1.85 +
    1.86 +	MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH);
    1.87 +	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
    1.88 +		seed[i] ^= seedmask[i];
    1.89 +
    1.90 +	OPENSSL_free(dbmask);
    1.91 +	return 1;
    1.92 +	}
    1.93 +
    1.94 +EXPORT_C int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
    1.95 +	const unsigned char *from, int flen, int num,
    1.96 +	const unsigned char *param, int plen)
    1.97 +	{
    1.98 +	int i, dblen, mlen = -1;
    1.99 +	const unsigned char *maskeddb;
   1.100 +	int lzero;
   1.101 +	unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
   1.102 +	int bad = 0;
   1.103 +
   1.104 +	if (--num < 2 * SHA_DIGEST_LENGTH + 1)
   1.105 +		/* 'num' is the length of the modulus, i.e. does not depend on the
   1.106 +		 * particular ciphertext. */
   1.107 +		goto decoding_err;
   1.108 +
   1.109 +	lzero = num - flen;
   1.110 +	if (lzero < 0)
   1.111 +		{
   1.112 +		/* lzero == -1 */
   1.113 +
   1.114 +		/* signalling this error immediately after detection might allow
   1.115 +		 * for side-channel attacks (e.g. timing if 'plen' is huge
   1.116 +		 * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
   1.117 +		 * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
   1.118 +		 * so we use a 'bad' flag */
   1.119 +		bad = 1;
   1.120 +		lzero = 0;
   1.121 +		}
   1.122 +	maskeddb = from - lzero + SHA_DIGEST_LENGTH;
   1.123 +
   1.124 +	dblen = num - SHA_DIGEST_LENGTH;
   1.125 +	db = OPENSSL_malloc(dblen);
   1.126 +	if (db == NULL)
   1.127 +		{
   1.128 +		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
   1.129 +		return -1;
   1.130 +		}
   1.131 +
   1.132 +	MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
   1.133 +	for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
   1.134 +		seed[i] ^= from[i - lzero];
   1.135 +  
   1.136 +	MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
   1.137 +	for (i = 0; i < dblen; i++)
   1.138 +		db[i] ^= maskeddb[i];
   1.139 +
   1.140 +	EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
   1.141 +
   1.142 +	if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
   1.143 +		goto decoding_err;
   1.144 +	else
   1.145 +		{
   1.146 +		for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
   1.147 +			if (db[i] != 0x00)
   1.148 +				break;
   1.149 +		if (db[i] != 0x01 || i++ >= dblen)
   1.150 +			goto decoding_err;
   1.151 +		else
   1.152 +			{
   1.153 +			/* everything looks OK */
   1.154 +
   1.155 +			mlen = dblen - i;
   1.156 +			if (tlen < mlen)
   1.157 +				{
   1.158 +				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
   1.159 +				mlen = -1;
   1.160 +				}
   1.161 +			else
   1.162 +				memcpy(to, db + i, mlen);
   1.163 +			}
   1.164 +		}
   1.165 +	OPENSSL_free(db);
   1.166 +	return mlen;
   1.167 +
   1.168 +decoding_err:
   1.169 +	/* to avoid chosen ciphertext attacks, the error message should not reveal
   1.170 +	 * which kind of decoding error happened */
   1.171 +	RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
   1.172 +	if (db != NULL) OPENSSL_free(db);
   1.173 +	return -1;
   1.174 +	}
   1.175 +
   1.176 +EXPORT_C int PKCS1_MGF1(unsigned char *mask, long len,
   1.177 +	const unsigned char *seed, long seedlen, const EVP_MD *dgst)
   1.178 +	{
   1.179 +	long i, outlen = 0;
   1.180 +	unsigned char cnt[4];
   1.181 +	EVP_MD_CTX c;
   1.182 +	unsigned char md[EVP_MAX_MD_SIZE];
   1.183 +	int mdlen;
   1.184 +
   1.185 +	EVP_MD_CTX_init(&c);
   1.186 +	mdlen = EVP_MD_size(dgst);
   1.187 +	for (i = 0; outlen < len; i++)
   1.188 +		{
   1.189 +		cnt[0] = (unsigned char)((i >> 24) & 255);
   1.190 +		cnt[1] = (unsigned char)((i >> 16) & 255);
   1.191 +		cnt[2] = (unsigned char)((i >> 8)) & 255;
   1.192 +		cnt[3] = (unsigned char)(i & 255);
   1.193 +		EVP_DigestInit_ex(&c,dgst, NULL);
   1.194 +		EVP_DigestUpdate(&c, seed, seedlen);
   1.195 +		EVP_DigestUpdate(&c, cnt, 4);
   1.196 +		if (outlen + mdlen <= len)
   1.197 +			{
   1.198 +			EVP_DigestFinal_ex(&c, mask + outlen, NULL);
   1.199 +			outlen += mdlen;
   1.200 +			}
   1.201 +		else
   1.202 +			{
   1.203 +			EVP_DigestFinal_ex(&c, md, NULL);
   1.204 +			memcpy(mask + outlen, md, len - outlen);
   1.205 +			outlen = len;
   1.206 +			}
   1.207 +		}
   1.208 +	EVP_MD_CTX_cleanup(&c);
   1.209 +	return 0;
   1.210 +	}
   1.211 +
   1.212 +EXPORT_C int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen)
   1.213 +	{
   1.214 +	return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
   1.215 +	}
   1.216 +#endif