Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 1 | /* crypto/rsa/rsa_eay.c */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * This package is an SSL implementation written |
| 6 | * by Eric Young (eay@cryptsoft.com). |
| 7 | * The implementation was written so as to conform with Netscapes SSL. |
| 8 | * |
| 9 | * This library is free for commercial and non-commercial use as long as |
| 10 | * the following conditions are aheared to. The following conditions |
| 11 | * apply to all code found in this distribution, be it the RC4, RSA, |
| 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
| 13 | * included with this distribution is covered by the same copyright terms |
| 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
| 15 | * |
| 16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
| 17 | * the code are not to be removed. |
| 18 | * If this package is used in a product, Eric Young should be given attribution |
| 19 | * as the author of the parts of the library used. |
| 20 | * This can be in the form of a textual message at program startup or |
| 21 | * in documentation (online or textual) provided with the package. |
| 22 | * |
| 23 | * Redistribution and use in source and binary forms, with or without |
| 24 | * modification, are permitted provided that the following conditions |
| 25 | * are met: |
| 26 | * 1. Redistributions of source code must retain the copyright |
| 27 | * notice, this list of conditions and the following disclaimer. |
| 28 | * 2. Redistributions in binary form must reproduce the above copyright |
| 29 | * notice, this list of conditions and the following disclaimer in the |
| 30 | * documentation and/or other materials provided with the distribution. |
| 31 | * 3. All advertising materials mentioning features or use of this software |
| 32 | * must display the following acknowledgement: |
| 33 | * "This product includes cryptographic software written by |
| 34 | * Eric Young (eay@cryptsoft.com)" |
| 35 | * The word 'cryptographic' can be left out if the rouines from the library |
| 36 | * being used are not cryptographic related :-). |
| 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
| 38 | * the apps directory (application code) you must include an acknowledgement: |
| 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
| 40 | * |
| 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
| 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 51 | * SUCH DAMAGE. |
| 52 | * |
| 53 | * The licence and distribution terms for any publically available version or |
| 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
| 55 | * copied and put under another distribution licence |
| 56 | * [including the GNU Public Licence.] |
| 57 | */ |
| 58 | |
| 59 | #include <stdio.h> |
| 60 | #include "cryptlib.h" |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 61 | #include <openssl/bn.h> |
| 62 | #include <openssl/rsa.h> |
| 63 | #include <openssl/rand.h> |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 64 | |
Dr. Stephen Henson | c1cd88a | 1999-09-08 18:19:45 +0000 | [diff] [blame] | 65 | #ifndef RSA_NULL |
| 66 | |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 67 | static int RSA_eay_public_encrypt(int flen, const unsigned char *from, |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 68 | unsigned char *to, RSA *rsa,int padding); |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 69 | static int RSA_eay_private_encrypt(int flen, const unsigned char *from, |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 70 | unsigned char *to, RSA *rsa,int padding); |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 71 | static int RSA_eay_public_decrypt(int flen, const unsigned char *from, |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 72 | unsigned char *to, RSA *rsa,int padding); |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 73 | static int RSA_eay_private_decrypt(int flen, const unsigned char *from, |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 74 | unsigned char *to, RSA *rsa,int padding); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 75 | static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 76 | static int RSA_eay_init(RSA *rsa); |
| 77 | static int RSA_eay_finish(RSA *rsa); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 78 | static RSA_METHOD rsa_pkcs1_eay_meth={ |
| 79 | "Eric Young's PKCS#1 RSA", |
| 80 | RSA_eay_public_encrypt, |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 81 | RSA_eay_public_decrypt, /* signature verification */ |
| 82 | RSA_eay_private_encrypt, /* signing */ |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 83 | RSA_eay_private_decrypt, |
| 84 | RSA_eay_mod_exp, |
Bodo Möller | 123d24d | 2000-12-18 16:39:00 +0000 | [diff] [blame] | 85 | BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 86 | RSA_eay_init, |
| 87 | RSA_eay_finish, |
Bodo Möller | be6d770 | 2001-09-20 15:41:34 +0000 | [diff] [blame] | 88 | 0, /* flags */ |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 89 | NULL, |
Bodo Möller | be6d770 | 2001-09-20 15:41:34 +0000 | [diff] [blame] | 90 | 0, /* rsa_sign */ |
Geoff Thorpe | 2814c62 | 2003-01-07 05:51:39 +0000 | [diff] [blame] | 91 | 0, /* rsa_verify */ |
| 92 | NULL /* rsa_keygen */ |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 93 | }; |
| 94 | |
Richard Levitte | 7be7c2e | 2000-11-07 13:49:46 +0000 | [diff] [blame] | 95 | const RSA_METHOD *RSA_PKCS1_SSLeay(void) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 96 | { |
| 97 | return(&rsa_pkcs1_eay_meth); |
| 98 | } |
| 99 | |
Geoff Thorpe | 79221bc | 2003-02-14 23:21:19 +0000 | [diff] [blame] | 100 | /* Static helper to reduce oodles of code duplication. As a slight |
| 101 | * optimisation, the "MONT_HELPER() macro must be used as front-end to this |
| 102 | * function, to prevent unnecessary function calls - there is an initial test |
| 103 | * that is performed by the macro-generated code. */ |
| 104 | static int rsa_eay_mont_helper(BN_MONT_CTX **ptr, const BIGNUM *modulus, BN_CTX *ctx) |
| 105 | { |
| 106 | BN_MONT_CTX *bn_mont_ctx; |
| 107 | if((bn_mont_ctx = BN_MONT_CTX_new()) == NULL) |
| 108 | return 0; |
| 109 | if(!BN_MONT_CTX_set(bn_mont_ctx, modulus, ctx)) |
| 110 | { |
| 111 | BN_MONT_CTX_free(bn_mont_ctx); |
| 112 | return 0; |
| 113 | } |
| 114 | if (*ptr == NULL) /* other thread may have finished first */ |
| 115 | { |
| 116 | CRYPTO_w_lock(CRYPTO_LOCK_RSA); |
| 117 | if (*ptr == NULL) /* check again in the lock to stop races */ |
| 118 | { |
| 119 | *ptr = bn_mont_ctx; |
| 120 | bn_mont_ctx = NULL; |
| 121 | } |
| 122 | CRYPTO_w_unlock(CRYPTO_LOCK_RSA); |
| 123 | } |
| 124 | if (bn_mont_ctx) |
| 125 | BN_MONT_CTX_free(bn_mont_ctx); |
| 126 | return 1; |
| 127 | } |
| 128 | /* Usage example; |
| 129 | * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); |
| 130 | */ |
| 131 | #define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ |
| 132 | if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ |
| 133 | !rsa_eay_mont_helper(&((rsa)->_method_mod_##m), \ |
| 134 | (rsa)->m, (ctx))) \ |
| 135 | err_instr |
| 136 | |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 137 | static int RSA_eay_public_encrypt(int flen, const unsigned char *from, |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 138 | unsigned char *to, RSA *rsa, int padding) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 139 | { |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 140 | BIGNUM *f,*ret; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 141 | int i,j,k,num=0,r= -1; |
| 142 | unsigned char *buf=NULL; |
| 143 | BN_CTX *ctx=NULL; |
| 144 | |
| 145 | if ((ctx=BN_CTX_new()) == NULL) goto err; |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 146 | BN_CTX_start(ctx); |
| 147 | f = BN_CTX_get(ctx); |
| 148 | ret = BN_CTX_get(ctx); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 149 | num=BN_num_bytes(rsa->n); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 150 | buf = OPENSSL_malloc(num); |
| 151 | if (!f || !ret || !buf) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 152 | { |
| 153 | RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE); |
| 154 | goto err; |
| 155 | } |
| 156 | |
| 157 | switch (padding) |
| 158 | { |
| 159 | case RSA_PKCS1_PADDING: |
| 160 | i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen); |
| 161 | break; |
Richard Levitte | cf1b7d9 | 2001-02-19 16:06:34 +0000 | [diff] [blame] | 162 | #ifndef OPENSSL_NO_SHA |
Ben Laurie | a494989 | 1999-02-17 21:11:08 +0000 | [diff] [blame] | 163 | case RSA_PKCS1_OAEP_PADDING: |
| 164 | i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0); |
| 165 | break; |
Ulf Möller | 79df9d6 | 1999-04-27 03:19:12 +0000 | [diff] [blame] | 166 | #endif |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 167 | case RSA_SSLV23_PADDING: |
| 168 | i=RSA_padding_add_SSLv23(buf,num,from,flen); |
| 169 | break; |
| 170 | case RSA_NO_PADDING: |
| 171 | i=RSA_padding_add_none(buf,num,from,flen); |
| 172 | break; |
| 173 | default: |
| 174 | RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); |
| 175 | goto err; |
| 176 | } |
| 177 | if (i <= 0) goto err; |
| 178 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 179 | if (BN_bin2bn(buf,num,f) == NULL) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 180 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 181 | if (BN_ucmp(f, rsa->n) >= 0) |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 182 | { |
| 183 | /* usually the padding functions would catch this */ |
| 184 | RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); |
| 185 | goto err; |
| 186 | } |
| 187 | |
Geoff Thorpe | 79221bc | 2003-02-14 23:21:19 +0000 | [diff] [blame] | 188 | MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); |
| 189 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 190 | if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, |
Ben Laurie | 03f8b04 | 1998-12-29 17:22:31 +0000 | [diff] [blame] | 191 | rsa->_method_mod_n)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 192 | |
| 193 | /* put in leading 0 bytes if the number is less than the |
| 194 | * length of the modulus */ |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 195 | j=BN_num_bytes(ret); |
| 196 | i=BN_bn2bin(ret,&(to[num-j])); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 197 | for (k=0; k<(num-i); k++) |
| 198 | to[k]=0; |
| 199 | |
| 200 | r=num; |
| 201 | err: |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 202 | if (ctx != NULL) |
| 203 | { |
| 204 | BN_CTX_end(ctx); |
| 205 | BN_CTX_free(ctx); |
| 206 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 207 | if (buf != NULL) |
| 208 | { |
Richard Levitte | 4579924 | 2002-11-28 08:04:36 +0000 | [diff] [blame] | 209 | OPENSSL_cleanse(buf,num); |
Richard Levitte | 26a3a48 | 2000-06-01 22:19:21 +0000 | [diff] [blame] | 210 | OPENSSL_free(buf); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 211 | } |
| 212 | return(r); |
| 213 | } |
| 214 | |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 215 | static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx) |
| 216 | { |
| 217 | BN_BLINDING *ret; |
Bodo Möller | c554155 | 2003-03-20 17:31:30 +0000 | [diff] [blame] | 218 | |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 219 | if (rsa->blinding == NULL) |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 220 | { |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 221 | if (rsa->blinding == NULL) |
| 222 | { |
| 223 | CRYPTO_w_lock(CRYPTO_LOCK_RSA); |
| 224 | if (rsa->blinding == NULL) |
| 225 | rsa->blinding = RSA_setup_blinding(rsa, ctx); |
| 226 | CRYPTO_w_unlock(CRYPTO_LOCK_RSA); |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | ret = rsa->blinding; |
| 231 | if (ret == NULL) |
| 232 | return NULL; |
| 233 | |
| 234 | if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id()) |
| 235 | { |
| 236 | *local = 0; |
| 237 | if (rsa->mt_blinding == NULL) |
| 238 | { |
| 239 | CRYPTO_w_lock(CRYPTO_LOCK_RSA); |
| 240 | if (rsa->mt_blinding == NULL) |
| 241 | rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); |
| 242 | CRYPTO_w_unlock(CRYPTO_LOCK_RSA); |
| 243 | } |
| 244 | ret = rsa->mt_blinding; |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 245 | } |
| 246 | else |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 247 | *local = 1; |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 248 | |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 249 | return ret; |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 250 | } |
| 251 | |
| 252 | static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f, |
| 253 | BIGNUM *r, BN_CTX *ctx) |
| 254 | { |
| 255 | if (local) |
| 256 | return BN_BLINDING_convert_ex(f, NULL, b, ctx); |
| 257 | else |
| 258 | { |
| 259 | int ret; |
| 260 | CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); |
| 261 | ret = BN_BLINDING_convert_ex(f, r, b, ctx); |
| 262 | CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); |
| 263 | return ret; |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f, |
| 268 | BIGNUM *r, BN_CTX *ctx) |
| 269 | { |
| 270 | if (local) |
| 271 | return BN_BLINDING_invert_ex(f, NULL, b, ctx); |
| 272 | else |
| 273 | { |
| 274 | int ret; |
| 275 | CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING); |
| 276 | ret = BN_BLINDING_invert_ex(f, r, b, ctx); |
| 277 | CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING); |
| 278 | return ret; |
| 279 | } |
| 280 | } |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 281 | |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 282 | /* signing */ |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 283 | static int RSA_eay_private_encrypt(int flen, const unsigned char *from, |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 284 | unsigned char *to, RSA *rsa, int padding) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 285 | { |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 286 | BIGNUM *f, *ret, *br; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 287 | int i,j,k,num=0,r= -1; |
| 288 | unsigned char *buf=NULL; |
| 289 | BN_CTX *ctx=NULL; |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 290 | int local_blinding = 0; |
| 291 | BN_BLINDING *blinding = NULL; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 292 | |
| 293 | if ((ctx=BN_CTX_new()) == NULL) goto err; |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 294 | BN_CTX_start(ctx); |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 295 | f = BN_CTX_get(ctx); |
| 296 | br = BN_CTX_get(ctx); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 297 | ret = BN_CTX_get(ctx); |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 298 | num = BN_num_bytes(rsa->n); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 299 | buf = OPENSSL_malloc(num); |
| 300 | if(!f || !ret || !buf) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 301 | { |
| 302 | RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); |
| 303 | goto err; |
| 304 | } |
| 305 | |
| 306 | switch (padding) |
| 307 | { |
| 308 | case RSA_PKCS1_PADDING: |
| 309 | i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); |
| 310 | break; |
| 311 | case RSA_NO_PADDING: |
| 312 | i=RSA_padding_add_none(buf,num,from,flen); |
| 313 | break; |
| 314 | case RSA_SSLV23_PADDING: |
| 315 | default: |
| 316 | RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); |
| 317 | goto err; |
| 318 | } |
| 319 | if (i <= 0) goto err; |
| 320 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 321 | if (BN_bin2bn(buf,num,f) == NULL) goto err; |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 322 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 323 | if (BN_ucmp(f, rsa->n) >= 0) |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 324 | { |
| 325 | /* usually the padding functions would catch this */ |
| 326 | RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); |
| 327 | goto err; |
| 328 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 329 | |
Bodo Möller | c554155 | 2003-03-20 17:31:30 +0000 | [diff] [blame] | 330 | if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 331 | { |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 332 | blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx); |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 333 | if (blinding == NULL) |
| 334 | { |
| 335 | RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); |
| 336 | goto err; |
| 337 | } |
| 338 | } |
| 339 | |
| 340 | if (blinding != NULL) |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 341 | if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) |
| 342 | goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 343 | |
Dr. Stephen Henson | 770d19b | 1999-07-27 21:58:08 +0000 | [diff] [blame] | 344 | if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || |
| 345 | ((rsa->p != NULL) && |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 346 | (rsa->q != NULL) && |
| 347 | (rsa->dmp1 != NULL) && |
| 348 | (rsa->dmq1 != NULL) && |
Dr. Stephen Henson | 770d19b | 1999-07-27 21:58:08 +0000 | [diff] [blame] | 349 | (rsa->iqmp != NULL)) ) |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 350 | { if (!rsa->meth->rsa_mod_exp(ret,f,rsa,ctx)) goto err; } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 351 | else |
| 352 | { |
Geoff Thorpe | b12753d | 2003-02-15 00:18:38 +0000 | [diff] [blame] | 353 | MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 354 | if (!rsa->meth->bn_mod_exp(ret,f,rsa->d,rsa->n,ctx, |
Geoff Thorpe | b12753d | 2003-02-15 00:18:38 +0000 | [diff] [blame] | 355 | rsa->_method_mod_n)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 356 | } |
| 357 | |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 358 | if (blinding) |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 359 | if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) |
| 360 | goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 361 | |
| 362 | /* put in leading 0 bytes if the number is less than the |
| 363 | * length of the modulus */ |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 364 | j=BN_num_bytes(ret); |
| 365 | i=BN_bn2bin(ret,&(to[num-j])); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 366 | for (k=0; k<(num-i); k++) |
| 367 | to[k]=0; |
| 368 | |
| 369 | r=num; |
| 370 | err: |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 371 | if (ctx != NULL) |
| 372 | { |
| 373 | BN_CTX_end(ctx); |
| 374 | BN_CTX_free(ctx); |
| 375 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 376 | if (buf != NULL) |
| 377 | { |
Richard Levitte | 4579924 | 2002-11-28 08:04:36 +0000 | [diff] [blame] | 378 | OPENSSL_cleanse(buf,num); |
Richard Levitte | 26a3a48 | 2000-06-01 22:19:21 +0000 | [diff] [blame] | 379 | OPENSSL_free(buf); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 380 | } |
| 381 | return(r); |
| 382 | } |
| 383 | |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 384 | static int RSA_eay_private_decrypt(int flen, const unsigned char *from, |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 385 | unsigned char *to, RSA *rsa, int padding) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 386 | { |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 387 | BIGNUM *f, *ret, *br; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 388 | int j,num=0,r= -1; |
| 389 | unsigned char *p; |
| 390 | unsigned char *buf=NULL; |
| 391 | BN_CTX *ctx=NULL; |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 392 | int local_blinding = 0; |
| 393 | BN_BLINDING *blinding = NULL; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 394 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 395 | if((ctx = BN_CTX_new()) == NULL) goto err; |
| 396 | BN_CTX_start(ctx); |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 397 | f = BN_CTX_get(ctx); |
| 398 | br = BN_CTX_get(ctx); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 399 | ret = BN_CTX_get(ctx); |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 400 | num = BN_num_bytes(rsa->n); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 401 | buf = OPENSSL_malloc(num); |
| 402 | if(!f || !ret || !buf) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 403 | { |
| 404 | RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); |
| 405 | goto err; |
| 406 | } |
| 407 | |
Ulf Möller | 657e60f | 2000-02-03 23:23:24 +0000 | [diff] [blame] | 408 | /* This check was for equality but PGP does evil things |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 409 | * and chops off the top '0' bytes */ |
| 410 | if (flen > num) |
| 411 | { |
| 412 | RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); |
| 413 | goto err; |
| 414 | } |
| 415 | |
| 416 | /* make data into a big number */ |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 417 | if (BN_bin2bn(from,(int)flen,f) == NULL) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 418 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 419 | if (BN_ucmp(f, rsa->n) >= 0) |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 420 | { |
| 421 | RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); |
| 422 | goto err; |
| 423 | } |
| 424 | |
Bodo Möller | c554155 | 2003-03-20 17:31:30 +0000 | [diff] [blame] | 425 | if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 426 | { |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 427 | blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx); |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 428 | if (blinding == NULL) |
| 429 | { |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 430 | RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 431 | goto err; |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | if (blinding != NULL) |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 436 | if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) |
| 437 | goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 438 | |
| 439 | /* do the decrypt */ |
Dr. Stephen Henson | 770d19b | 1999-07-27 21:58:08 +0000 | [diff] [blame] | 440 | if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || |
| 441 | ((rsa->p != NULL) && |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 442 | (rsa->q != NULL) && |
| 443 | (rsa->dmp1 != NULL) && |
| 444 | (rsa->dmq1 != NULL) && |
Dr. Stephen Henson | 770d19b | 1999-07-27 21:58:08 +0000 | [diff] [blame] | 445 | (rsa->iqmp != NULL)) ) |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 446 | { if (!rsa->meth->rsa_mod_exp(ret,f,rsa,ctx)) goto err; } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 447 | else |
| 448 | { |
Geoff Thorpe | b12753d | 2003-02-15 00:18:38 +0000 | [diff] [blame] | 449 | MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 450 | if (!rsa->meth->bn_mod_exp(ret,f,rsa->d,rsa->n,ctx, |
Geoff Thorpe | b12753d | 2003-02-15 00:18:38 +0000 | [diff] [blame] | 451 | rsa->_method_mod_n)) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 452 | goto err; |
| 453 | } |
| 454 | |
Bodo Möller | 5679bcc | 2003-04-02 09:50:22 +0000 | [diff] [blame] | 455 | if (blinding) |
Nils Larsch | 800e400 | 2005-04-26 22:31:48 +0000 | [diff] [blame^] | 456 | if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) |
| 457 | goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 458 | |
| 459 | p=buf; |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 460 | j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */ |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 461 | |
| 462 | switch (padding) |
| 463 | { |
| 464 | case RSA_PKCS1_PADDING: |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 465 | r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 466 | break; |
Richard Levitte | cf1b7d9 | 2001-02-19 16:06:34 +0000 | [diff] [blame] | 467 | #ifndef OPENSSL_NO_SHA |
Ben Laurie | a494989 | 1999-02-17 21:11:08 +0000 | [diff] [blame] | 468 | case RSA_PKCS1_OAEP_PADDING: |
| 469 | r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); |
| 470 | break; |
Ulf Möller | 79df9d6 | 1999-04-27 03:19:12 +0000 | [diff] [blame] | 471 | #endif |
Ben Laurie | a494989 | 1999-02-17 21:11:08 +0000 | [diff] [blame] | 472 | case RSA_SSLV23_PADDING: |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 473 | r=RSA_padding_check_SSLv23(to,num,buf,j,num); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 474 | break; |
| 475 | case RSA_NO_PADDING: |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 476 | r=RSA_padding_check_none(to,num,buf,j,num); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 477 | break; |
| 478 | default: |
| 479 | RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); |
| 480 | goto err; |
| 481 | } |
| 482 | if (r < 0) |
| 483 | RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); |
| 484 | |
| 485 | err: |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 486 | if (ctx != NULL) |
| 487 | { |
| 488 | BN_CTX_end(ctx); |
| 489 | BN_CTX_free(ctx); |
| 490 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 491 | if (buf != NULL) |
| 492 | { |
Richard Levitte | 4579924 | 2002-11-28 08:04:36 +0000 | [diff] [blame] | 493 | OPENSSL_cleanse(buf,num); |
Richard Levitte | 26a3a48 | 2000-06-01 22:19:21 +0000 | [diff] [blame] | 494 | OPENSSL_free(buf); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 495 | } |
| 496 | return(r); |
| 497 | } |
| 498 | |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 499 | /* signature verification */ |
Richard Levitte | 29c1f06 | 2000-11-06 22:34:17 +0000 | [diff] [blame] | 500 | static int RSA_eay_public_decrypt(int flen, const unsigned char *from, |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 501 | unsigned char *to, RSA *rsa, int padding) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 502 | { |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 503 | BIGNUM *f,*ret; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 504 | int i,num=0,r= -1; |
| 505 | unsigned char *p; |
| 506 | unsigned char *buf=NULL; |
| 507 | BN_CTX *ctx=NULL; |
| 508 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 509 | if((ctx = BN_CTX_new()) == NULL) goto err; |
| 510 | BN_CTX_start(ctx); |
| 511 | f = BN_CTX_get(ctx); |
| 512 | ret = BN_CTX_get(ctx); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 513 | num=BN_num_bytes(rsa->n); |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 514 | buf = OPENSSL_malloc(num); |
| 515 | if(!f || !ret || !buf) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 516 | { |
| 517 | RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE); |
| 518 | goto err; |
| 519 | } |
| 520 | |
Ulf Möller | 657e60f | 2000-02-03 23:23:24 +0000 | [diff] [blame] | 521 | /* This check was for equality but PGP does evil things |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 522 | * and chops off the top '0' bytes */ |
| 523 | if (flen > num) |
| 524 | { |
| 525 | RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); |
| 526 | goto err; |
| 527 | } |
| 528 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 529 | if (BN_bin2bn(from,flen,f) == NULL) goto err; |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 530 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 531 | if (BN_ucmp(f, rsa->n) >= 0) |
Bodo Möller | 24cff6c | 2001-07-25 17:02:58 +0000 | [diff] [blame] | 532 | { |
| 533 | RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); |
| 534 | goto err; |
| 535 | } |
| 536 | |
Geoff Thorpe | 79221bc | 2003-02-14 23:21:19 +0000 | [diff] [blame] | 537 | MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); |
| 538 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 539 | if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, |
Ben Laurie | 03f8b04 | 1998-12-29 17:22:31 +0000 | [diff] [blame] | 540 | rsa->_method_mod_n)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 541 | |
| 542 | p=buf; |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 543 | i=BN_bn2bin(ret,p); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 544 | |
| 545 | switch (padding) |
| 546 | { |
| 547 | case RSA_PKCS1_PADDING: |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 548 | r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 549 | break; |
| 550 | case RSA_NO_PADDING: |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 551 | r=RSA_padding_check_none(to,num,buf,i,num); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 552 | break; |
| 553 | default: |
| 554 | RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); |
| 555 | goto err; |
| 556 | } |
| 557 | if (r < 0) |
| 558 | RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED); |
| 559 | |
| 560 | err: |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 561 | if (ctx != NULL) |
| 562 | { |
| 563 | BN_CTX_end(ctx); |
| 564 | BN_CTX_free(ctx); |
| 565 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 566 | if (buf != NULL) |
| 567 | { |
Richard Levitte | 4579924 | 2002-11-28 08:04:36 +0000 | [diff] [blame] | 568 | OPENSSL_cleanse(buf,num); |
Richard Levitte | 26a3a48 | 2000-06-01 22:19:21 +0000 | [diff] [blame] | 569 | OPENSSL_free(buf); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 570 | } |
| 571 | return(r); |
| 572 | } |
| 573 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 574 | static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 575 | { |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 576 | BIGNUM *r1,*m1,*vrfy; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 577 | int ret=0; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 578 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 579 | BN_CTX_start(ctx); |
| 580 | r1 = BN_CTX_get(ctx); |
| 581 | m1 = BN_CTX_get(ctx); |
| 582 | vrfy = BN_CTX_get(ctx); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 583 | |
Geoff Thorpe | 79221bc | 2003-02-14 23:21:19 +0000 | [diff] [blame] | 584 | MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); |
| 585 | MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); |
Geoff Thorpe | b12753d | 2003-02-15 00:18:38 +0000 | [diff] [blame] | 586 | MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); |
Bodo Möller | 126fe08 | 2000-12-19 12:31:41 +0000 | [diff] [blame] | 587 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 588 | if (!BN_mod(r1,I,rsa->q,ctx)) goto err; |
| 589 | if (!rsa->meth->bn_mod_exp(m1,r1,rsa->dmq1,rsa->q,ctx, |
Ben Laurie | 03f8b04 | 1998-12-29 17:22:31 +0000 | [diff] [blame] | 590 | rsa->_method_mod_q)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 591 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 592 | if (!BN_mod(r1,I,rsa->p,ctx)) goto err; |
| 593 | if (!rsa->meth->bn_mod_exp(r0,r1,rsa->dmp1,rsa->p,ctx, |
Ben Laurie | 03f8b04 | 1998-12-29 17:22:31 +0000 | [diff] [blame] | 594 | rsa->_method_mod_p)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 595 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 596 | if (!BN_sub(r0,r0,m1)) goto err; |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 597 | /* This will help stop the size of r0 increasing, which does |
| 598 | * affect the multiply if it optimised for a power of 2 size */ |
Nils Larsch | ff22e91 | 2005-04-22 20:02:44 +0000 | [diff] [blame] | 599 | if (BN_is_negative(r0)) |
Ralf S. Engelschall | dfeab06 | 1998-12-21 11:00:56 +0000 | [diff] [blame] | 600 | if (!BN_add(r0,r0,rsa->p)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 601 | |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 602 | if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; |
| 603 | if (!BN_mod(r0,r1,rsa->p,ctx)) goto err; |
Dr. Stephen Henson | abd4c91 | 1999-03-11 02:42:13 +0000 | [diff] [blame] | 604 | /* If p < q it is occasionally possible for the correction of |
| 605 | * adding 'p' if r0 is negative above to leave the result still |
| 606 | * negative. This can break the private key operations: the following |
| 607 | * second correction should *always* correct this rare occurrence. |
| 608 | * This will *never* happen with OpenSSL generated keys because |
| 609 | * they ensure p > q [steve] |
| 610 | */ |
Nils Larsch | ff22e91 | 2005-04-22 20:02:44 +0000 | [diff] [blame] | 611 | if (BN_is_negative(r0)) |
Dr. Stephen Henson | abd4c91 | 1999-03-11 02:42:13 +0000 | [diff] [blame] | 612 | if (!BN_add(r0,r0,rsa->p)) goto err; |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 613 | if (!BN_mul(r1,r0,rsa->q,ctx)) goto err; |
| 614 | if (!BN_add(r0,r1,m1)) goto err; |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 615 | |
Ulf Möller | 6a5b52e | 2001-03-28 04:56:58 +0000 | [diff] [blame] | 616 | if (rsa->e && rsa->n) |
| 617 | { |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 618 | if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; |
Geoff Thorpe | 81d1998 | 2001-07-20 15:16:10 +0000 | [diff] [blame] | 619 | /* If 'I' was greater than (or equal to) rsa->n, the operation |
| 620 | * will be equivalent to using 'I mod n'. However, the result of |
| 621 | * the verify will *always* be less than 'n' so we don't check |
| 622 | * for absolute equality, just congruency. */ |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 623 | if (!BN_sub(vrfy, vrfy, I)) goto err; |
| 624 | if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; |
Nils Larsch | ff22e91 | 2005-04-22 20:02:44 +0000 | [diff] [blame] | 625 | if (BN_is_negative(vrfy)) |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 626 | if (!BN_add(vrfy, vrfy, rsa->n)) goto err; |
| 627 | if (!BN_is_zero(vrfy)) |
Geoff Thorpe | 81d1998 | 2001-07-20 15:16:10 +0000 | [diff] [blame] | 628 | /* 'I' and 'vrfy' aren't congruent mod n. Don't leak |
| 629 | * miscalculated CRT output, just do a raw (slower) |
| 630 | * mod_exp and return that instead. */ |
Geoff Thorpe | b12753d | 2003-02-15 00:18:38 +0000 | [diff] [blame] | 631 | if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx, |
| 632 | rsa->_method_mod_n)) goto err; |
Ulf Möller | 6a5b52e | 2001-03-28 04:56:58 +0000 | [diff] [blame] | 633 | } |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 634 | ret=1; |
| 635 | err: |
Geoff Thorpe | 46ef873 | 2004-03-25 02:52:04 +0000 | [diff] [blame] | 636 | BN_CTX_end(ctx); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 637 | return(ret); |
| 638 | } |
| 639 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 640 | static int RSA_eay_init(RSA *rsa) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 641 | { |
| 642 | rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE; |
| 643 | return(1); |
| 644 | } |
| 645 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 646 | static int RSA_eay_finish(RSA *rsa) |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 647 | { |
Ben Laurie | 03f8b04 | 1998-12-29 17:22:31 +0000 | [diff] [blame] | 648 | if (rsa->_method_mod_n != NULL) |
| 649 | BN_MONT_CTX_free(rsa->_method_mod_n); |
| 650 | if (rsa->_method_mod_p != NULL) |
| 651 | BN_MONT_CTX_free(rsa->_method_mod_p); |
| 652 | if (rsa->_method_mod_q != NULL) |
| 653 | BN_MONT_CTX_free(rsa->_method_mod_q); |
Ralf S. Engelschall | 58964a4 | 1998-12-21 10:56:39 +0000 | [diff] [blame] | 654 | return(1); |
| 655 | } |
| 656 | |
Dr. Stephen Henson | c1cd88a | 1999-09-08 18:19:45 +0000 | [diff] [blame] | 657 | #endif |