diff options
Diffstat (limited to 'crypto/bn/bn_div.c')
-rw-r--r-- | crypto/bn/bn_div.c | 111 |
1 files changed, 26 insertions, 85 deletions
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c index bc37671cf138..70add10c7d6c 100644 --- a/crypto/bn/bn_div.c +++ b/crypto/bn/bn_div.c @@ -1,64 +1,14 @@ -/* crypto/bn/bn_div.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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 acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS 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 AUTHOR OR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ -#include <stdio.h> #include <openssl/bn.h> -#include "cryptlib.h" +#include "internal/cryptlib.h" #include "bn_lcl.h" /* The old slow way */ @@ -74,17 +24,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, bn_check_top(d); if (BN_is_zero(d)) { BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); - return (0); + return 0; } if (BN_ucmp(m, d) < 0) { if (rem != NULL) { if (BN_copy(rem, m) == NULL) - return (0); + return 0; } if (dv != NULL) BN_zero(dv); - return (1); + return 1; } BN_CTX_start(ctx); @@ -131,7 +81,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, ret = 1; end: BN_CTX_end(ctx); - return (ret); + return ret; } #else @@ -147,8 +97,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, * understand why...); * - divl doesn't only calculate quotient, but also leaves * remainder in %edx which we can definitely use here:-) - * - * <appro@fy.chalmers.se> */ # undef bn_div_words # define bn_div_words(n0,n1,d0) \ @@ -163,7 +111,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, # elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) /* * Same story here, but it's 128-bit by 64-bit division. Wow! - * <appro@fy.chalmers.se> */ # undef bn_div_words # define bn_div_words(n0,n1,d0) \ @@ -180,7 +127,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, # endif /* OPENSSL_NO_ASM */ /*- - * BN_div computes dv := num / divisor, rounding towards + * BN_div computes dv := num / divisor, rounding towards * zero, and sets up rm such that dv*divisor + rm = num holds. * Thus: * dv->neg == num->neg ^ divisor->neg (unless the result is zero) @@ -227,28 +174,25 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, if (BN_is_zero(divisor)) { BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); - return (0); + return 0; } if (!no_branch && BN_ucmp(num, divisor) < 0) { if (rm != NULL) { if (BN_copy(rm, num) == NULL) - return (0); + return 0; } if (dv != NULL) BN_zero(dv); - return (1); + return 1; } BN_CTX_start(ctx); + res = (dv == NULL) ? BN_CTX_get(ctx) : dv; tmp = BN_CTX_get(ctx); snum = BN_CTX_get(ctx); sdiv = BN_CTX_get(ctx); - if (dv == NULL) - res = BN_CTX_get(ctx); - else - res = dv; - if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL) + if (sdiv == NULL) goto err; /* First we normalise the numbers */ @@ -290,6 +234,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, wnum.neg = 0; wnum.d = &(snum->d[loop]); wnum.top = div_n; + wnum.flags = BN_FLG_STATIC_DATA; /* * only needed when BN_ucmp messes up the values between top and max */ @@ -304,9 +249,9 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, wnump = &(snum->d[num_n - 1]); /* Setup to 'res' */ - res->neg = (num->neg ^ divisor->neg); if (!bn_wexpand(res, (loop + 1))) goto err; + res->neg = (num->neg ^ divisor->neg); res->top = loop - no_branch; resp = &(res->d[loop - 1]); @@ -328,6 +273,9 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, res->top--; } + /* Increase the resp pointer so that we never create an invalid pointer. */ + resp++; + /* * if res->top == 0 then clear the neg value otherwise decrease the resp * pointer @@ -337,7 +285,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, else resp--; - for (i = 0; i < loop - 1; i++, wnump--, resp--) { + for (i = 0; i < loop - 1; i++, wnump--) { BN_ULONG q, l0; /* * the first part of the loop uses the top two words of snum and sdiv @@ -362,10 +310,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0); # else q = bn_div_words(n0, n1, d0); -# ifdef BN_DEBUG_LEVITTE - fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ -X) -> 0x%08X\n", n0, n1, d0, q); -# endif # endif # ifndef REMAINDER_IS_ALREADY_CALCULATED @@ -390,10 +334,6 @@ X) -> 0x%08X\n", n0, n1, d0, q); BN_ULONG t2l, t2h; q = bn_div_words(n0, n1, d0); -# ifdef BN_DEBUG_LEVITTE - fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ -X) -> 0x%08X\n", n0, n1, d0, q); -# endif # ifndef REMAINDER_IS_ALREADY_CALCULATED rem = (n1 - q * d0) & BN_MASK2; # endif @@ -451,6 +391,7 @@ X) -> 0x%08X\n", n0, n1, d0, q); (*wnump)++; } /* store part of the result */ + resp--; *resp = q; } bn_correct_top(snum); @@ -468,10 +409,10 @@ X) -> 0x%08X\n", n0, n1, d0, q); if (no_branch) bn_correct_top(res); BN_CTX_end(ctx); - return (1); + return 1; err: bn_check_top(rm); BN_CTX_end(ctx); - return (0); + return 0; } #endif |