diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_mod.c')
| -rw-r--r-- | src/lib/libcrypto/bn/bn_mod.c | 207 |
1 files changed, 110 insertions, 97 deletions
diff --git a/src/lib/libcrypto/bn/bn_mod.c b/src/lib/libcrypto/bn/bn_mod.c index 6c439402dd..dae388ac84 100644 --- a/src/lib/libcrypto/bn/bn_mod.c +++ b/src/lib/libcrypto/bn/bn_mod.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * are met: | 9 | * are met: |
| 10 | * | 10 | * |
| 11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * | 13 | * |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 15 | * notice, this list of conditions and the following disclaimer in | 15 | * notice, this list of conditions and the following disclaimer in |
| @@ -60,21 +60,21 @@ | |||
| 60 | * This package is an SSL implementation written | 60 | * This package is an SSL implementation written |
| 61 | * by Eric Young (eay@cryptsoft.com). | 61 | * by Eric Young (eay@cryptsoft.com). |
| 62 | * The implementation was written so as to conform with Netscapes SSL. | 62 | * The implementation was written so as to conform with Netscapes SSL. |
| 63 | * | 63 | * |
| 64 | * This library is free for commercial and non-commercial use as long as | 64 | * This library is free for commercial and non-commercial use as long as |
| 65 | * the following conditions are aheared to. The following conditions | 65 | * the following conditions are aheared to. The following conditions |
| 66 | * apply to all code found in this distribution, be it the RC4, RSA, | 66 | * apply to all code found in this distribution, be it the RC4, RSA, |
| 67 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | 67 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
| 68 | * included with this distribution is covered by the same copyright terms | 68 | * included with this distribution is covered by the same copyright terms |
| 69 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | 69 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
| 70 | * | 70 | * |
| 71 | * Copyright remains Eric Young's, and as such any Copyright notices in | 71 | * Copyright remains Eric Young's, and as such any Copyright notices in |
| 72 | * the code are not to be removed. | 72 | * the code are not to be removed. |
| 73 | * If this package is used in a product, Eric Young should be given attribution | 73 | * If this package is used in a product, Eric Young should be given attribution |
| 74 | * as the author of the parts of the library used. | 74 | * as the author of the parts of the library used. |
| 75 | * This can be in the form of a textual message at program startup or | 75 | * This can be in the form of a textual message at program startup or |
| 76 | * in documentation (online or textual) provided with the package. | 76 | * in documentation (online or textual) provided with the package. |
| 77 | * | 77 | * |
| 78 | * Redistribution and use in source and binary forms, with or without | 78 | * Redistribution and use in source and binary forms, with or without |
| 79 | * modification, are permitted provided that the following conditions | 79 | * modification, are permitted provided that the following conditions |
| 80 | * are met: | 80 | * are met: |
| @@ -89,10 +89,10 @@ | |||
| 89 | * Eric Young (eay@cryptsoft.com)" | 89 | * Eric Young (eay@cryptsoft.com)" |
| 90 | * The word 'cryptographic' can be left out if the rouines from the library | 90 | * The word 'cryptographic' can be left out if the rouines from the library |
| 91 | * being used are not cryptographic related :-). | 91 | * being used are not cryptographic related :-). |
| 92 | * 4. If you include any Windows specific code (or a derivative thereof) from | 92 | * 4. If you include any Windows specific code (or a derivative thereof) from |
| 93 | * the apps directory (application code) you must include an acknowledgement: | 93 | * the apps directory (application code) you must include an acknowledgement: |
| 94 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | 94 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
| 95 | * | 95 | * |
| 96 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | 96 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
| 97 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 97 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 98 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 98 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -104,7 +104,7 @@ | |||
| 104 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 104 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 105 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 105 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 106 | * SUCH DAMAGE. | 106 | * SUCH DAMAGE. |
| 107 | * | 107 | * |
| 108 | * The licence and distribution terms for any publically available version or | 108 | * The licence and distribution terms for any publically available version or |
| 109 | * derivative of this code cannot be changed. i.e. this code cannot simply be | 109 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
| 110 | * copied and put under another distribution licence | 110 | * copied and put under another distribution licence |
| @@ -114,13 +114,13 @@ | |||
| 114 | #include "cryptlib.h" | 114 | #include "cryptlib.h" |
| 115 | #include "bn_lcl.h" | 115 | #include "bn_lcl.h" |
| 116 | 116 | ||
| 117 | 117 | int | |
| 118 | int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) | 118 | BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) |
| 119 | { | 119 | { |
| 120 | /* like BN_mod, but returns non-negative remainder | 120 | /* like BN_mod, but returns non-negative remainder |
| 121 | * (i.e., 0 <= r < |d| always holds) */ | 121 | * (i.e., 0 <= r < |d| always holds) */ |
| 122 | 122 | ||
| 123 | if (!(BN_mod(r,m,d,ctx))) | 123 | if (!(BN_mod(r, m,d, ctx))) |
| 124 | return 0; | 124 | return 0; |
| 125 | if (!r->neg) | 125 | if (!r->neg) |
| 126 | return 1; | 126 | return 1; |
| @@ -128,165 +128,178 @@ int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) | |||
| 128 | return (d->neg ? BN_sub : BN_add)(r, r, d); | 128 | return (d->neg ? BN_sub : BN_add)(r, r, d); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | 131 | int | |
| 132 | int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) | 132 | BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, |
| 133 | { | 133 | BN_CTX *ctx) |
| 134 | if (!BN_add(r, a, b)) return 0; | 134 | { |
| 135 | if (!BN_add(r, a, b)) | ||
| 136 | return 0; | ||
| 135 | return BN_nnmod(r, r, m, ctx); | 137 | return BN_nnmod(r, r, m, ctx); |
| 136 | } | 138 | } |
| 137 | |||
| 138 | 139 | ||
| 139 | /* BN_mod_add variant that may be used if both a and b are non-negative | 140 | /* BN_mod_add variant that may be used if both a and b are non-negative |
| 140 | * and less than m */ | 141 | * and less than m */ |
| 141 | int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) | 142 | int |
| 142 | { | 143 | BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) |
| 143 | if (!BN_uadd(r, a, b)) return 0; | 144 | { |
| 145 | if (!BN_uadd(r, a, b)) | ||
| 146 | return 0; | ||
| 144 | if (BN_ucmp(r, m) >= 0) | 147 | if (BN_ucmp(r, m) >= 0) |
| 145 | return BN_usub(r, r, m); | 148 | return BN_usub(r, r, m); |
| 146 | return 1; | 149 | return 1; |
| 147 | } | 150 | } |
| 148 | |||
| 149 | 151 | ||
| 150 | int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) | 152 | int |
| 151 | { | 153 | BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, |
| 152 | if (!BN_sub(r, a, b)) return 0; | 154 | BN_CTX *ctx) |
| 155 | { | ||
| 156 | if (!BN_sub(r, a, b)) | ||
| 157 | return 0; | ||
| 153 | return BN_nnmod(r, r, m, ctx); | 158 | return BN_nnmod(r, r, m, ctx); |
| 154 | } | 159 | } |
| 155 | |||
| 156 | 160 | ||
| 157 | /* BN_mod_sub variant that may be used if both a and b are non-negative | 161 | /* BN_mod_sub variant that may be used if both a and b are non-negative |
| 158 | * and less than m */ | 162 | * and less than m */ |
| 159 | int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) | 163 | int |
| 160 | { | 164 | BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m) |
| 161 | if (!BN_sub(r, a, b)) return 0; | 165 | { |
| 166 | if (!BN_sub(r, a, b)) | ||
| 167 | return 0; | ||
| 162 | if (r->neg) | 168 | if (r->neg) |
| 163 | return BN_add(r, r, m); | 169 | return BN_add(r, r, m); |
| 164 | return 1; | 170 | return 1; |
| 165 | } | 171 | } |
| 166 | |||
| 167 | 172 | ||
| 168 | /* slow but works */ | 173 | /* slow but works */ |
| 169 | int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, | 174 | int |
| 170 | BN_CTX *ctx) | 175 | BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, |
| 171 | { | 176 | BN_CTX *ctx) |
| 177 | { | ||
| 172 | BIGNUM *t; | 178 | BIGNUM *t; |
| 173 | int ret=0; | 179 | int ret = 0; |
| 174 | 180 | ||
| 175 | bn_check_top(a); | 181 | bn_check_top(a); |
| 176 | bn_check_top(b); | 182 | bn_check_top(b); |
| 177 | bn_check_top(m); | 183 | bn_check_top(m); |
| 178 | 184 | ||
| 179 | BN_CTX_start(ctx); | 185 | BN_CTX_start(ctx); |
| 180 | if ((t = BN_CTX_get(ctx)) == NULL) goto err; | 186 | if ((t = BN_CTX_get(ctx)) == NULL) |
| 181 | if (a == b) | 187 | goto err; |
| 182 | { if (!BN_sqr(t,a,ctx)) goto err; } | 188 | if (a == b) { |
| 183 | else | 189 | if (!BN_sqr(t, a, ctx)) |
| 184 | { if (!BN_mul(t,a,b,ctx)) goto err; } | 190 | goto err; |
| 185 | if (!BN_nnmod(r,t,m,ctx)) goto err; | 191 | } else { |
| 192 | if (!BN_mul(t, a,b, ctx)) | ||
| 193 | goto err; | ||
| 194 | } | ||
| 195 | if (!BN_nnmod(r, t,m, ctx)) | ||
| 196 | goto err; | ||
| 186 | bn_check_top(r); | 197 | bn_check_top(r); |
| 187 | ret=1; | 198 | ret = 1; |
| 199 | |||
| 188 | err: | 200 | err: |
| 189 | BN_CTX_end(ctx); | 201 | BN_CTX_end(ctx); |
| 190 | return(ret); | 202 | return (ret); |
| 191 | } | 203 | } |
| 192 | |||
| 193 | 204 | ||
| 194 | int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | 205 | int |
| 195 | { | 206 | BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) |
| 196 | if (!BN_sqr(r, a, ctx)) return 0; | 207 | { |
| 208 | if (!BN_sqr(r, a, ctx)) | ||
| 209 | return 0; | ||
| 197 | /* r->neg == 0, thus we don't need BN_nnmod */ | 210 | /* r->neg == 0, thus we don't need BN_nnmod */ |
| 198 | return BN_mod(r, r, m, ctx); | 211 | return BN_mod(r, r, m, ctx); |
| 199 | } | 212 | } |
| 200 | |||
| 201 | 213 | ||
| 202 | int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) | 214 | int |
| 203 | { | 215 | BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) |
| 204 | if (!BN_lshift1(r, a)) return 0; | 216 | { |
| 217 | if (!BN_lshift1(r, a)) | ||
| 218 | return 0; | ||
| 205 | bn_check_top(r); | 219 | bn_check_top(r); |
| 206 | return BN_nnmod(r, r, m, ctx); | 220 | return BN_nnmod(r, r, m, ctx); |
| 207 | } | 221 | } |
| 208 | |||
| 209 | 222 | ||
| 210 | /* BN_mod_lshift1 variant that may be used if a is non-negative | 223 | /* BN_mod_lshift1 variant that may be used if a is non-negative |
| 211 | * and less than m */ | 224 | * and less than m */ |
| 212 | int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) | 225 | int |
| 213 | { | 226 | BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) |
| 214 | if (!BN_lshift1(r, a)) return 0; | 227 | { |
| 228 | if (!BN_lshift1(r, a)) | ||
| 229 | return 0; | ||
| 215 | bn_check_top(r); | 230 | bn_check_top(r); |
| 216 | if (BN_cmp(r, m) >= 0) | 231 | if (BN_cmp(r, m) >= 0) |
| 217 | return BN_sub(r, r, m); | 232 | return BN_sub(r, r, m); |
| 218 | return 1; | 233 | return 1; |
| 219 | } | 234 | } |
| 220 | |||
| 221 | 235 | ||
| 222 | int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx) | 236 | int |
| 223 | { | 237 | BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx) |
| 238 | { | ||
| 224 | BIGNUM *abs_m = NULL; | 239 | BIGNUM *abs_m = NULL; |
| 225 | int ret; | 240 | int ret; |
| 226 | 241 | ||
| 227 | if (!BN_nnmod(r, a, m, ctx)) return 0; | 242 | if (!BN_nnmod(r, a, m, ctx)) |
| 243 | return 0; | ||
| 228 | 244 | ||
| 229 | if (m->neg) | 245 | if (m->neg) { |
| 230 | { | ||
| 231 | abs_m = BN_dup(m); | 246 | abs_m = BN_dup(m); |
| 232 | if (abs_m == NULL) return 0; | 247 | if (abs_m == NULL) |
| 248 | return 0; | ||
| 233 | abs_m->neg = 0; | 249 | abs_m->neg = 0; |
| 234 | } | 250 | } |
| 235 | 251 | ||
| 236 | ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); | 252 | ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); |
| 237 | bn_check_top(r); | 253 | bn_check_top(r); |
| 238 | 254 | ||
| 239 | if (abs_m) | 255 | if (abs_m) |
| 240 | BN_free(abs_m); | 256 | BN_free(abs_m); |
| 241 | return ret; | 257 | return ret; |
| 242 | } | 258 | } |
| 243 | |||
| 244 | 259 | ||
| 245 | /* BN_mod_lshift variant that may be used if a is non-negative | 260 | /* BN_mod_lshift variant that may be used if a is non-negative |
| 246 | * and less than m */ | 261 | * and less than m */ |
| 247 | int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) | 262 | int |
| 248 | { | 263 | BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) |
| 249 | if (r != a) | 264 | { |
| 250 | { | 265 | if (r != a) { |
| 251 | if (BN_copy(r, a) == NULL) return 0; | 266 | if (BN_copy(r, a) == NULL) |
| 252 | } | 267 | return 0; |
| 268 | } | ||
| 253 | 269 | ||
| 254 | while (n > 0) | 270 | while (n > 0) { |
| 255 | { | ||
| 256 | int max_shift; | 271 | int max_shift; |
| 257 | 272 | ||
| 258 | /* 0 < r < m */ | 273 | /* 0 < r < m */ |
| 259 | max_shift = BN_num_bits(m) - BN_num_bits(r); | 274 | max_shift = BN_num_bits(m) - BN_num_bits(r); |
| 260 | /* max_shift >= 0 */ | 275 | /* max_shift >= 0 */ |
| 261 | 276 | ||
| 262 | if (max_shift < 0) | 277 | if (max_shift < 0) { |
| 263 | { | ||
| 264 | BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); | 278 | BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); |
| 265 | return 0; | 279 | return 0; |
| 266 | } | 280 | } |
| 267 | 281 | ||
| 268 | if (max_shift > n) | 282 | if (max_shift > n) |
| 269 | max_shift = n; | 283 | max_shift = n; |
| 270 | 284 | ||
| 271 | if (max_shift) | 285 | if (max_shift) { |
| 272 | { | 286 | if (!BN_lshift(r, r, max_shift)) |
| 273 | if (!BN_lshift(r, r, max_shift)) return 0; | 287 | return 0; |
| 274 | n -= max_shift; | 288 | n -= max_shift; |
| 275 | } | 289 | } else { |
| 276 | else | 290 | if (!BN_lshift1(r, r)) |
| 277 | { | 291 | return 0; |
| 278 | if (!BN_lshift1(r, r)) return 0; | ||
| 279 | --n; | 292 | --n; |
| 280 | } | 293 | } |
| 281 | 294 | ||
| 282 | /* BN_num_bits(r) <= BN_num_bits(m) */ | 295 | /* BN_num_bits(r) <= BN_num_bits(m) */ |
| 283 | 296 | ||
| 284 | if (BN_cmp(r, m) >= 0) | 297 | if (BN_cmp(r, m) >= 0) { |
| 285 | { | 298 | if (!BN_sub(r, r, m)) |
| 286 | if (!BN_sub(r, r, m)) return 0; | 299 | return 0; |
| 287 | } | ||
| 288 | } | 300 | } |
| 301 | } | ||
| 289 | bn_check_top(r); | 302 | bn_check_top(r); |
| 290 | 303 | ||
| 291 | return 1; | 304 | return 1; |
| 292 | } | 305 | } |
