197b2ed56SKris Kennaway /* crypto/rsa/rsa_sign.c */ 297b2ed56SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 397b2ed56SKris Kennaway * All rights reserved. 497b2ed56SKris Kennaway * 597b2ed56SKris Kennaway * This package is an SSL implementation written 697b2ed56SKris Kennaway * by Eric Young (eay@cryptsoft.com). 797b2ed56SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 897b2ed56SKris Kennaway * 997b2ed56SKris Kennaway * This library is free for commercial and non-commercial use as long as 1097b2ed56SKris Kennaway * the following conditions are aheared to. The following conditions 1197b2ed56SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1297b2ed56SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1397b2ed56SKris Kennaway * included with this distribution is covered by the same copyright terms 1497b2ed56SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1597b2ed56SKris Kennaway * 1697b2ed56SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1797b2ed56SKris Kennaway * the code are not to be removed. 1897b2ed56SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 1997b2ed56SKris Kennaway * as the author of the parts of the library used. 2097b2ed56SKris Kennaway * This can be in the form of a textual message at program startup or 2197b2ed56SKris Kennaway * in documentation (online or textual) provided with the package. 2297b2ed56SKris Kennaway * 2397b2ed56SKris Kennaway * Redistribution and use in source and binary forms, with or without 2497b2ed56SKris Kennaway * modification, are permitted provided that the following conditions 2597b2ed56SKris Kennaway * are met: 2697b2ed56SKris Kennaway * 1. Redistributions of source code must retain the copyright 2797b2ed56SKris Kennaway * notice, this list of conditions and the following disclaimer. 2897b2ed56SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 2997b2ed56SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3097b2ed56SKris Kennaway * documentation and/or other materials provided with the distribution. 3197b2ed56SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3297b2ed56SKris Kennaway * must display the following acknowledgement: 3397b2ed56SKris Kennaway * "This product includes cryptographic software written by 3497b2ed56SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3597b2ed56SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3697b2ed56SKris Kennaway * being used are not cryptographic related :-). 3797b2ed56SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 3897b2ed56SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 3997b2ed56SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4097b2ed56SKris Kennaway * 4197b2ed56SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4297b2ed56SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4397b2ed56SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4497b2ed56SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4597b2ed56SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4697b2ed56SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4797b2ed56SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4897b2ed56SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4997b2ed56SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5097b2ed56SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5197b2ed56SKris Kennaway * SUCH DAMAGE. 5297b2ed56SKris Kennaway * 5397b2ed56SKris Kennaway * The licence and distribution terms for any publically available version or 5497b2ed56SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5597b2ed56SKris Kennaway * copied and put under another distribution licence 5697b2ed56SKris Kennaway * [including the GNU Public Licence.] 5797b2ed56SKris Kennaway */ 5897b2ed56SKris Kennaway 5997b2ed56SKris Kennaway #include <stdio.h> 6097b2ed56SKris Kennaway #include "cryptlib.h" 6197b2ed56SKris Kennaway #include <openssl/bn.h> 6297b2ed56SKris Kennaway #include <openssl/rsa.h> 6397b2ed56SKris Kennaway #include <openssl/objects.h> 6497b2ed56SKris Kennaway #include <openssl/x509.h> 651f13597dSJung-uk Kim #include "rsa_locl.h" 6697b2ed56SKris Kennaway 67f579bf8eSKris Kennaway /* Size of an SSL signature: MD5+SHA1 */ 68f579bf8eSKris Kennaway #define SSL_SIG_LENGTH 36 69f579bf8eSKris Kennaway 705c87c606SMark Murray int RSA_sign(int type, const unsigned char *m, unsigned int m_len, 7197b2ed56SKris Kennaway unsigned char *sigret, unsigned int *siglen, RSA *rsa) 7297b2ed56SKris Kennaway { 7397b2ed56SKris Kennaway X509_SIG sig; 7497b2ed56SKris Kennaway ASN1_TYPE parameter; 7597b2ed56SKris Kennaway int i, j, ret = 1; 765c87c606SMark Murray unsigned char *p, *tmps = NULL; 775c87c606SMark Murray const unsigned char *s = NULL; 7897b2ed56SKris Kennaway X509_ALGOR algor; 7997b2ed56SKris Kennaway ASN1_OCTET_STRING digest; 801f13597dSJung-uk Kim #ifdef OPENSSL_FIPS 811f13597dSJung-uk Kim if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 826f9291ceSJung-uk Kim && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { 831f13597dSJung-uk Kim RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); 841f13597dSJung-uk Kim return 0; 851f13597dSJung-uk Kim } 861f13597dSJung-uk Kim #endif 876f9291ceSJung-uk Kim if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { 886f9291ceSJung-uk Kim return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); 8950ef0093SJacques Vidrine } 90f579bf8eSKris Kennaway /* Special case: SSL signature, just check the length */ 91f579bf8eSKris Kennaway if (type == NID_md5_sha1) { 92f579bf8eSKris Kennaway if (m_len != SSL_SIG_LENGTH) { 93f579bf8eSKris Kennaway RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); 94f579bf8eSKris Kennaway return (0); 95f579bf8eSKris Kennaway } 96f579bf8eSKris Kennaway i = SSL_SIG_LENGTH; 97f579bf8eSKris Kennaway s = m; 98f579bf8eSKris Kennaway } else { 9997b2ed56SKris Kennaway sig.algor = &algor; 10097b2ed56SKris Kennaway sig.algor->algorithm = OBJ_nid2obj(type); 1016f9291ceSJung-uk Kim if (sig.algor->algorithm == NULL) { 10297b2ed56SKris Kennaway RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); 10397b2ed56SKris Kennaway return (0); 10497b2ed56SKris Kennaway } 1056f9291ceSJung-uk Kim if (sig.algor->algorithm->length == 0) { 1066f9291ceSJung-uk Kim RSAerr(RSA_F_RSA_SIGN, 1076f9291ceSJung-uk Kim RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); 10897b2ed56SKris Kennaway return (0); 10997b2ed56SKris Kennaway } 11097b2ed56SKris Kennaway parameter.type = V_ASN1_NULL; 11197b2ed56SKris Kennaway parameter.value.ptr = NULL; 11297b2ed56SKris Kennaway sig.algor->parameter = ¶meter; 11397b2ed56SKris Kennaway 11497b2ed56SKris Kennaway sig.digest = &digest; 1155c87c606SMark Murray sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ 11697b2ed56SKris Kennaway sig.digest->length = m_len; 11797b2ed56SKris Kennaway 11897b2ed56SKris Kennaway i = i2d_X509_SIG(&sig, NULL); 119f579bf8eSKris Kennaway } 12097b2ed56SKris Kennaway j = RSA_size(rsa); 1216f9291ceSJung-uk Kim if (i > (j - RSA_PKCS1_PADDING_SIZE)) { 12297b2ed56SKris Kennaway RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); 12397b2ed56SKris Kennaway return (0); 12497b2ed56SKris Kennaway } 125f579bf8eSKris Kennaway if (type != NID_md5_sha1) { 1265c87c606SMark Murray tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); 1276f9291ceSJung-uk Kim if (tmps == NULL) { 12897b2ed56SKris Kennaway RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE); 12997b2ed56SKris Kennaway return (0); 13097b2ed56SKris Kennaway } 1315c87c606SMark Murray p = tmps; 13297b2ed56SKris Kennaway i2d_X509_SIG(&sig, &p); 1335c87c606SMark Murray s = tmps; 134f579bf8eSKris Kennaway } 13597b2ed56SKris Kennaway i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); 13697b2ed56SKris Kennaway if (i <= 0) 13797b2ed56SKris Kennaway ret = 0; 13897b2ed56SKris Kennaway else 13997b2ed56SKris Kennaway *siglen = i; 14097b2ed56SKris Kennaway 141f579bf8eSKris Kennaway if (type != NID_md5_sha1) { 1425c87c606SMark Murray OPENSSL_cleanse(tmps, (unsigned int)j + 1); 1435c87c606SMark Murray OPENSSL_free(tmps); 144f579bf8eSKris Kennaway } 14597b2ed56SKris Kennaway return (ret); 14697b2ed56SKris Kennaway } 14797b2ed56SKris Kennaway 148fa5fddf1SJung-uk Kim /* 149fa5fddf1SJung-uk Kim * Check DigestInfo structure does not contain extraneous data by reencoding 150fa5fddf1SJung-uk Kim * using DER and checking encoding against original. 151fa5fddf1SJung-uk Kim */ 1526f9291ceSJung-uk Kim static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, 1536f9291ceSJung-uk Kim int dinfolen) 154fa5fddf1SJung-uk Kim { 155fa5fddf1SJung-uk Kim unsigned char *der = NULL; 156fa5fddf1SJung-uk Kim int derlen; 157fa5fddf1SJung-uk Kim int ret = 0; 158fa5fddf1SJung-uk Kim derlen = i2d_X509_SIG(sig, &der); 159fa5fddf1SJung-uk Kim if (derlen <= 0) 160fa5fddf1SJung-uk Kim return 0; 161fa5fddf1SJung-uk Kim if (derlen == dinfolen && !memcmp(dinfo, der, derlen)) 162fa5fddf1SJung-uk Kim ret = 1; 163fa5fddf1SJung-uk Kim OPENSSL_cleanse(der, derlen); 164fa5fddf1SJung-uk Kim OPENSSL_free(der); 165fa5fddf1SJung-uk Kim return ret; 166fa5fddf1SJung-uk Kim } 167fa5fddf1SJung-uk Kim 1681f13597dSJung-uk Kim int int_rsa_verify(int dtype, const unsigned char *m, 1691f13597dSJung-uk Kim unsigned int m_len, 1701f13597dSJung-uk Kim unsigned char *rm, size_t *prm_len, 1716f9291ceSJung-uk Kim const unsigned char *sigbuf, size_t siglen, RSA *rsa) 17297b2ed56SKris Kennaway { 17397b2ed56SKris Kennaway int i, ret = 0, sigtype; 1743b4e3dcbSSimon L. B. Nielsen unsigned char *s; 17597b2ed56SKris Kennaway X509_SIG *sig = NULL; 17697b2ed56SKris Kennaway 1771f13597dSJung-uk Kim #ifdef OPENSSL_FIPS 1781f13597dSJung-uk Kim if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) 1796f9291ceSJung-uk Kim && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { 1801f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD); 1811f13597dSJung-uk Kim return 0; 1821f13597dSJung-uk Kim } 1831f13597dSJung-uk Kim #endif 1841f13597dSJung-uk Kim 1856f9291ceSJung-uk Kim if (siglen != (unsigned int)RSA_size(rsa)) { 1861f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); 18797b2ed56SKris Kennaway return (0); 18897b2ed56SKris Kennaway } 18997b2ed56SKris Kennaway 1906f9291ceSJung-uk Kim if ((dtype == NID_md5_sha1) && rm) { 1911f13597dSJung-uk Kim i = RSA_public_decrypt((int)siglen, 1921f13597dSJung-uk Kim sigbuf, rm, rsa, RSA_PKCS1_PADDING); 1931f13597dSJung-uk Kim if (i <= 0) 1941f13597dSJung-uk Kim return 0; 1951f13597dSJung-uk Kim *prm_len = i; 1961f13597dSJung-uk Kim return 1; 19750ef0093SJacques Vidrine } 198f579bf8eSKris Kennaway 199ddd58736SKris Kennaway s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); 2006f9291ceSJung-uk Kim if (s == NULL) { 2011f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); 20297b2ed56SKris Kennaway goto err; 20397b2ed56SKris Kennaway } 2041f13597dSJung-uk Kim if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) { 2051f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); 2063b4e3dcbSSimon L. B. Nielsen goto err; 207f579bf8eSKris Kennaway } 20897b2ed56SKris Kennaway i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); 20997b2ed56SKris Kennaway 2106f9291ceSJung-uk Kim if (i <= 0) 2116f9291ceSJung-uk Kim goto err; 2126f9291ceSJung-uk Kim /* 2136f9291ceSJung-uk Kim * Oddball MDC2 case: signature can be OCTET STRING. check for correct 2146f9291ceSJung-uk Kim * tag and length octets. 2151f13597dSJung-uk Kim */ 2166f9291ceSJung-uk Kim if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) { 2176f9291ceSJung-uk Kim if (rm) { 2181f13597dSJung-uk Kim memcpy(rm, s + 2, 16); 2191f13597dSJung-uk Kim *prm_len = 16; 2201f13597dSJung-uk Kim ret = 1; 221*80815a77SJung-uk Kim } else if (memcmp(m, s + 2, 16)) { 2221f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); 223*80815a77SJung-uk Kim } else { 2241f13597dSJung-uk Kim ret = 1; 2251f13597dSJung-uk Kim } 226*80815a77SJung-uk Kim } else if (dtype == NID_md5_sha1) { 227f579bf8eSKris Kennaway /* Special case: SSL signature */ 228f579bf8eSKris Kennaway if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) 2291f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); 2306f9291ceSJung-uk Kim else 2316f9291ceSJung-uk Kim ret = 1; 232f579bf8eSKris Kennaway } else { 2333b4e3dcbSSimon L. B. Nielsen const unsigned char *p = s; 23497b2ed56SKris Kennaway sig = d2i_X509_SIG(NULL, &p, (long)i); 23597b2ed56SKris Kennaway 2366f9291ceSJung-uk Kim if (sig == NULL) 2376f9291ceSJung-uk Kim goto err; 238c800238eSSimon L. B. Nielsen 239c800238eSSimon L. B. Nielsen /* Excess data can be used to create forgeries */ 2406f9291ceSJung-uk Kim if (p != s + i || !rsa_check_digestinfo(sig, s, i)) { 2411f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); 242c800238eSSimon L. B. Nielsen goto err; 243c800238eSSimon L. B. Nielsen } 244c800238eSSimon L. B. Nielsen 2456f9291ceSJung-uk Kim /* 2466f9291ceSJung-uk Kim * Parameters to the signature algorithm can also be used to create 2476f9291ceSJung-uk Kim * forgeries 2486f9291ceSJung-uk Kim */ 249c800238eSSimon L. B. Nielsen if (sig->algor->parameter 2506f9291ceSJung-uk Kim && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { 2511f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); 252c800238eSSimon L. B. Nielsen goto err; 253c800238eSSimon L. B. Nielsen } 254c800238eSSimon L. B. Nielsen 25597b2ed56SKris Kennaway sigtype = OBJ_obj2nid(sig->algor->algorithm); 25697b2ed56SKris Kennaway 25797b2ed56SKris Kennaway #ifdef RSA_DEBUG 258f579bf8eSKris Kennaway /* put a backward compatibility flag in EAY */ 25997b2ed56SKris Kennaway fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype), 26097b2ed56SKris Kennaway OBJ_nid2ln(dtype)); 26197b2ed56SKris Kennaway #endif 2626f9291ceSJung-uk Kim if (sigtype != dtype) { 2636f9291ceSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); 26497b2ed56SKris Kennaway goto err; 26597b2ed56SKris Kennaway } 2666f9291ceSJung-uk Kim if (rm) { 2671f13597dSJung-uk Kim const EVP_MD *md; 2681f13597dSJung-uk Kim md = EVP_get_digestbynid(dtype); 2691f13597dSJung-uk Kim if (md && (EVP_MD_size(md) != sig->digest->length)) 2706f9291ceSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); 2716f9291ceSJung-uk Kim else { 2726f9291ceSJung-uk Kim memcpy(rm, sig->digest->data, sig->digest->length); 2731f13597dSJung-uk Kim *prm_len = sig->digest->length; 2741f13597dSJung-uk Kim ret = 1; 2751f13597dSJung-uk Kim } 2766f9291ceSJung-uk Kim } else if (((unsigned int)sig->digest->length != m_len) || 2776f9291ceSJung-uk Kim (memcmp(m, sig->digest->data, m_len) != 0)) { 2781f13597dSJung-uk Kim RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); 2796f9291ceSJung-uk Kim } else 28097b2ed56SKris Kennaway ret = 1; 281f579bf8eSKris Kennaway } 28297b2ed56SKris Kennaway err: 2836f9291ceSJung-uk Kim if (sig != NULL) 2846f9291ceSJung-uk Kim X509_SIG_free(sig); 2856f9291ceSJung-uk Kim if (s != NULL) { 2865c87c606SMark Murray OPENSSL_cleanse(s, (unsigned int)siglen); 287ddd58736SKris Kennaway OPENSSL_free(s); 2883b4e3dcbSSimon L. B. Nielsen } 28997b2ed56SKris Kennaway return (ret); 29097b2ed56SKris Kennaway } 29197b2ed56SKris Kennaway 2921f13597dSJung-uk Kim int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, 2936f9291ceSJung-uk Kim const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) 2941f13597dSJung-uk Kim { 2951f13597dSJung-uk Kim 2966f9291ceSJung-uk Kim if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { 2976f9291ceSJung-uk Kim return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa); 2981f13597dSJung-uk Kim } 2991f13597dSJung-uk Kim 3001f13597dSJung-uk Kim return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); 3011f13597dSJung-uk Kim } 302