1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/bn/bn_lib.c */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com). 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL. 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to. The following conditions 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA, 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed. 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used. 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package. 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in the 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * documentation and/or other materials provided with the distribution. 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * must display the following acknowledgement: 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes cryptographic software written by 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Eric Young (eay@cryptsoft.com)" 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The word 'cryptographic' can be left out if the rouines from the library 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * being used are not cryptographic related :-). 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the apps directory (application code) you must include an acknowledgement: 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE. 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed. i.e. this code cannot simply be 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.] 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef BN_DEBUG 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# undef NDEBUG /* avoid conflicting definitions */ 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define NDEBUG 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h> 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <limits.h> 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h> 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h" 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "bn_lcl.h" 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT; 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This stuff appears to be completely unused, so is deprecated */ 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For a 32 bit machine 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2 - 4 == 128 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3 - 8 == 256 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4 - 16 == 512 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5 - 32 == 1024 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6 - 64 == 2048 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 7 - 128 == 4096 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8 - 256 == 8192 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_bits=0; 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_num=8; /* (1<<bn_limit_bits) */ 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_bits_low=0; 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */ 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_bits_high=0; 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */ 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_bits_mont=0; 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */ 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_set_params(int mult, int high, int low, int mont) 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (mult >= 0) 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (mult > (int)(sizeof(int)*8)-1) 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project mult=sizeof(int)*8-1; 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_bits=mult; 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_num=1<<mult; 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (high >= 0) 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (high > (int)(sizeof(int)*8)-1) 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project high=sizeof(int)*8-1; 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_bits_high=high; 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_num_high=1<<high; 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (low >= 0) 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (low > (int)(sizeof(int)*8)-1) 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project low=sizeof(int)*8-1; 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_bits_low=low; 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_num_low=1<<low; 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (mont >= 0) 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (mont > (int)(sizeof(int)*8)-1) 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project mont=sizeof(int)*8-1; 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_bits_mont=mont; 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_limit_num_mont=1<<mont; 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_get_params(int which) 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (which == 0) return(bn_limit_bits); 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (which == 1) return(bn_limit_bits_high); 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (which == 2) return(bn_limit_bits_low); 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (which == 3) return(bn_limit_bits_mont); 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(0); 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *BN_value_one(void) 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom static const BN_ULONG data_one=1L; 137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA}; 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(&const_one); 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_num_bits_word(BN_ULONG l) 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom static const unsigned char bits[256]={ 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project }; 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(SIXTY_FOUR_BIT_LONG) 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xffffffff00000000L) 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xffff000000000000L) 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xff00000000000000L) 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l>>56)]+56); 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(bits[(int)(l>>48)]+48); 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0x0000ff0000000000L) 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l>>40)]+40); 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(bits[(int)(l>>32)]+32); 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef SIXTY_FOUR_BIT 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xffffffff00000000LL) 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xffff000000000000LL) 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xff00000000000000LL) 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l>>56)]+56); 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(bits[(int)(l>>48)]+48); 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0x0000ff0000000000LL) 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l>>40)]+40); 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(bits[(int)(l>>32)]+32); 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xffff0000L) 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xff000000L) 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l>>24L)]+24); 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(bits[(int)(l>>16L)]+16); 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (l & 0xff00L) 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l>>8)]+8); 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(bits[(int)(l )] ); 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_num_bits(const BIGNUM *a) 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i = a->top - 1; 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_is_zero(a)) return 0; 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ((i*BN_BITS2) + BN_num_bits_word(a->d[i])); 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_clear_free(BIGNUM *a) 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a == NULL) return; 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->d != NULL) 245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0])); 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(BN_get_flags(a,BN_FLG_STATIC_DATA))) 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a->d); 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=BN_get_flags(a,BN_FLG_MALLOCED); 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_cleanse(a,sizeof(BIGNUM)); 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i) 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a); 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_free(BIGNUM *a) 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a == NULL) return; 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA))) 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a->d); 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->flags & BN_FLG_MALLOCED) 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a); 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->flags|=BN_FLG_FREE; 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d = NULL; 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_init(BIGNUM *a) 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memset(a,0,sizeof(BIGNUM)); 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *BN_new(void) 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *ret; 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE); 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->flags=BN_FLG_MALLOCED; 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->top=0; 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->neg=0; 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->dmax=0; 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->d=NULL; 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(ret); 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This is used both by bn_expand2() and bn_dup_expand() */ 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* The caller MUST check that words > b->dmax before calling this */ 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG *A,*a = NULL; 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BN_ULONG *B; 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (words > (INT_MAX/(4*BN_BITS2))) 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG); 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_get_flags(b,BN_FLG_STATIC_DATA)) 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words); 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (A == NULL) 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE); 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 323c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root#ifdef PURIFY 324c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root /* Valgrind complains in BN_consttime_swap because we process the whole 325c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root * array even if it's not initialised yet. This doesn't matter in that 326c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root * function - what's important is constant time operation (we're not 327c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root * actually going to use the data) 328c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root */ 329c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root memset(a, 0, sizeof(BN_ULONG)*words); 330c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root#endif 331c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 1 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project B=b->d; 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Check if the previous number needs to be copied */ 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (B != NULL) 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=b->top>>2; i>0; i--,A+=4,B+=4) 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The fact that the loop is unrolled 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4-wise is a tribute to Intel. It's 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the one that doesn't have enough 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * registers to accomodate more data. 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * I'd unroll it 8-wise otherwise:-) 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * <appro@fy.chalmers.se> 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG a0,a1,a2,a3; 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3]; 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3; 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (b->top&3) 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 3: A[2]=B[2]; 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 2: A[1]=B[1]; 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 1: A[0]=B[0]; 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the switch table by doing a=top&3; a--; goto jump_table[a]; 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * which fails for top== 0 */ 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ; 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memset(A,0,sizeof(BN_ULONG)*words); 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(A,b->d,sizeof(b->d[0])*b->top); 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(a); 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This is an internal function that can be used instead of bn_expand2() 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * when there is a need to copy BIGNUMs instead of only expanding the 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * data part, while still expanding them. 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Especially useful when needing to expand BIGNUMs that are declared 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 'const' and should therefore not be changed. 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The reason to use this instead of a BN_dup() followed by a bn_expand2() 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * is memory allocation overhead. A BN_dup() followed by a bn_expand2() 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * will allocate new memory for the BIGNUM data twice, and free it once, 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * while bn_dup_expand() makes sure allocation is made only once. 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_DEPRECATED 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *bn_dup_expand(const BIGNUM *b, int words) 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *r = NULL; 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* This function does not work if 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * words <= b->dmax && top < words 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * because BN_dup() does not preserve 'dmax'! 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (But bn_dup_expand() is not used anywhere yet.) 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (words > b->dmax) 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG *a = bn_expand_internal(b, words); 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a) 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BN_new(); 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r) 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r->top = b->top; 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r->dmax = words; 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r->neg = b->neg; 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r->d = a; 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* r == NULL, BN_new failure */ 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(a); 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* If a == NULL, there was an error in allocation in 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_expand_internal(), and NULL should be returned */ 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = BN_dup(b); 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(r); 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return r; 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This is an internal function that should not be used in applications. 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * It ensures that 'b' has enough room for a 'words' word number 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and initialises any unused part of b->d with leading zeros. 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * It is mostly used by the various BIGNUM routines. If there is an error, 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NULL is returned. If not, 'b' is returned. */ 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *bn_expand2(BIGNUM *b, int words) 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (words > b->dmax) 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG *a = bn_expand_internal(b, words); 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!a) return NULL; 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(b->d) OPENSSL_free(b->d); 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->d=a; 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->dmax=words; 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* None of this should be necessary because of what b->top means! */ 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */ 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->top < b->dmax) 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG *A = &(b->d[b->top]); 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8) 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project A[0]=0; A[1]=0; A[2]=0; A[3]=0; 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project A[4]=0; A[5]=0; A[6]=0; A[7]=0; 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=(b->dmax - b->top)&7; i>0; i--,A++) 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project A[0]=0; 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project assert(A == &(b->d[b->dmax])); 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return b; 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *BN_dup(const BIGNUM *a) 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *t; 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a == NULL) return NULL; 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t = BN_new(); 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t == NULL) return NULL; 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!BN_copy(t, a)) 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(t); 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(t); 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return t; 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG *A; 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BN_ULONG *B; 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a == b) return(a); 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bn_wexpand(a,b->top) == NULL) return(NULL); 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 1 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project A=a->d; 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project B=b->d; 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=b->top>>2; i>0; i--,A+=4,B+=4) 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG a0,a1,a2,a3; 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3]; 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3; 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (b->top&3) 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 3: A[2]=B[2]; 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 2: A[1]=B[1]; 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 1: A[0]=B[0]; 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */ 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memcpy(a->d,b->d,sizeof(b->d[0])*b->top); 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top=b->top; 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->neg=b->neg; 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(a); 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_swap(BIGNUM *a, BIGNUM *b) 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int flags_old_a, flags_old_b; 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG *tmp_d; 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int tmp_top, tmp_dmax, tmp_neg; 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project flags_old_a = a->flags; 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project flags_old_b = b->flags; 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_d = a->d; 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_top = a->top; 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_dmax = a->dmax; 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project tmp_neg = a->neg; 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d = b->d; 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top = b->top; 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->dmax = b->dmax; 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->neg = b->neg; 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->d = tmp_d; 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->top = tmp_top; 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->dmax = tmp_dmax; 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->neg = tmp_neg; 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA); 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA); 553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_clear(BIGNUM *a) 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->d != NULL) 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project memset(a->d,0,a->dmax*sizeof(a->d[0])); 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top=0; 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->neg=0; 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBN_ULONG BN_get_word(const BIGNUM *a) 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->top > 1) 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_MASK2; 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (a->top == 1) 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return a->d[0]; 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* a->top == 0 */ 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_set_word(BIGNUM *a, BN_ULONG w) 577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0); 580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->neg = 0; 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d[0] = w; 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top = (w ? 1 : 0); 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) 588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned int i,m; 590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned int n; 591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG l; 592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *bn = NULL; 593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == NULL) 595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = bn = BN_new(); 596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == NULL) return(NULL); 597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(ret); 598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project l=0; 599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project n=len; 600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (n == 0) 601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->top=0; 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=((n-1)/BN_BYTES)+1; 606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project m=((n-1)%(BN_BYTES)); 607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bn_wexpand(ret, (int)i) == NULL) 608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bn) BN_free(bn); 610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->top=i; 613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->neg=0; 614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (n--) 615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project l=(l<<8L)| *(s++); 617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (m-- == 0) 618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->d[--i]=l; 620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project l=0; 621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project m=BN_BYTES-1; 622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* need to call this due to clear byte at top if avoiding 625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * having the top bit set (-ve number) */ 626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_correct_top(ret); 627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ignore negative */ 631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_bn2bin(const BIGNUM *a, unsigned char *to) 632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int n,i; 634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG l; 635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project n=i=BN_num_bytes(a); 638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (i--) 639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project l=a->d[i/BN_BYTES]; 641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff; 642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(n); 644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_ucmp(const BIGNUM *a, const BIGNUM *b) 647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG t1,t2,*ap,*bp; 650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=a->top-b->top; 655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i != 0) return(i); 656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ap=a->d; 657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bp=b->d; 658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=a->top-1; i>=0; i--) 659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t1= ap[i]; 661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t2= bp[i]; 662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t1 != t2) 663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return((t1 > t2) ? 1 : -1); 664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_cmp(const BIGNUM *a, const BIGNUM *b) 669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int gt,lt; 672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG t1,t2; 673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((a == NULL) || (b == NULL)) 675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a != NULL) 677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(-1); 678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if (b != NULL) 679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(b); 686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->neg != b->neg) 688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->neg) 690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(-1); 691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else return(1); 692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->neg == 0) 694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { gt=1; lt= -1; } 695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else { gt= -1; lt=1; } 696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->top > b->top) return(gt); 698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->top < b->top) return(lt); 699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=a->top-1; i>=0; i--) 700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t1=a->d[i]; 702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t2=b->d[i]; 703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t1 > t2) return(gt); 704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t1 < t2) return(lt); 705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_set_bit(BIGNUM *a, int n) 710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i,j,k; 712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (n < 0) 714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=n/BN_BITS2; 717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project j=n%BN_BITS2; 718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->top <= i) 719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bn_wexpand(a,i+1) == NULL) return(0); 721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for(k=a->top; k<i+1; k++) 722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d[k]=0; 723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top=i+1; 724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d[i]|=(((BN_ULONG)1)<<j); 727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_clear_bit(BIGNUM *a, int n) 732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i,j; 734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (n < 0) return 0; 737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=n/BN_BITS2; 739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project j=n%BN_BITS2; 740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->top <= i) return(0); 741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d[i]&=(~(((BN_ULONG)1)<<j)); 743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_correct_top(a); 744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_is_bit_set(const BIGNUM *a, int n) 748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i,j; 750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (n < 0) return 0; 753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=n/BN_BITS2; 754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project j=n%BN_BITS2; 755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->top <= i) return 0; 756221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return (int)(((a->d[i])>>j)&((BN_ULONG)1)); 757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_mask_bits(BIGNUM *a, int n) 760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int b,w; 762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_check_top(a); 764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (n < 0) return 0; 765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project w=n/BN_BITS2; 767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b=n%BN_BITS2; 768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (w >= a->top) return 0; 769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b == 0) 770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top=w; 771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->top=w+1; 774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->d[w]&= ~(BN_MASK2<<b); 775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bn_correct_top(a); 777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(1); 778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid BN_set_negative(BIGNUM *a, int b) 781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b && !BN_is_zero(a)) 783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->neg = 1; 784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project a->neg = 0; 786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) 789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_ULONG aa,bb; 792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aa=a[n-1]; 794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bb=b[n-1]; 795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aa != bb) return((aa > bb)?1:-1); 796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=n-2; i>=0; i--) 797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aa=a[i]; 799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bb=b[i]; 800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (aa != bb) return((aa > bb)?1:-1); 801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(0); 803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Here follows a specialised variants of bn_cmp_words(). It has the 806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project property of performing the operation on arrays of different sizes. 807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project The sizes of those arrays is expressed through cl, which is the 808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project common length ( basicall, min(len(a),len(b)) ), and dl, which is the 809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project delta between the two lengths, calculated as len(a)-len(b). 810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project All lengths are the number of BN_ULONGs... */ 811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, 813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int cl, int dl) 814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int n,i; 816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project n = cl-1; 817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dl < 0) 819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=dl; i<0; i++) 821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b[n-i] != 0) 823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; /* a < b */ 824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dl > 0) 827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i=dl; i>0; i--) 829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a[n+i] != 0) 831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; /* a > b */ 832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return bn_cmp_words(a,b,cl); 835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 8367f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8377f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root/* 8387f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root * Constant-time conditional swap of a and b. 8397f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. 8407f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, 8417f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root * and that no more than nwords are used by either a or b. 8427f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root * a and b cannot be the same number 8437f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root */ 8447f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Rootvoid BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) 8457f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root { 8467f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root BN_ULONG t; 8477f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root int i; 8487f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8497f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root bn_wcheck_size(a, nwords); 8507f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root bn_wcheck_size(b, nwords); 8517f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8527f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root assert(a != b); 8537f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root assert((condition & (condition - 1)) == 0); 8547f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root assert(sizeof(BN_ULONG) >= sizeof(int)); 8557f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8567f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; 8577f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8587f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root t = (a->top^b->top) & condition; 8597f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root a->top ^= t; 8607f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root b->top ^= t; 8617f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8627f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root#define BN_CONSTTIME_SWAP(ind) \ 8637f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root do { \ 8647f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root t = (a->d[ind] ^ b->d[ind]) & condition; \ 8657f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root a->d[ind] ^= t; \ 8667f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root b->d[ind] ^= t; \ 8677f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root } while (0) 8687f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8697f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root 8707f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root switch (nwords) { 8717f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root default: 8727f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root for (i = 10; i < nwords; i++) 8737f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root BN_CONSTTIME_SWAP(i); 8747f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root /* Fallthrough */ 8757f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ 8767f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ 8777f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ 8787f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ 8797f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ 8807f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ 8817f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ 8827f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ 8837f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ 8847f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root case 1: BN_CONSTTIME_SWAP(0); 8857f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root } 8867f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root#undef BN_CONSTTIME_SWAP 8877f7ea2d72f2e316ba518e82f06513e3477840c15Kenny Root} 888