⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bn.c

📁 samba最新软件
💻 C
字号:
/* * Copyright (c) 2006 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * 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 above 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. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.  */#ifdef HAVE_CONFIG_H#include <config.h>#endifRCSID("$Id: bn.c 22261 2007-12-09 06:24:18Z lha $");#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <krb5-types.h>#include <rfc2459_asn1.h> /* XXX */#include <der.h>#include <bn.h>#include <rand.h>#include <hex.h>BIGNUM *BN_new(void){    heim_integer *hi;    hi = calloc(1, sizeof(*hi));    return (BIGNUM *)hi;}voidBN_free(BIGNUM *bn){    BN_clear(bn);    free(bn);}voidBN_clear(BIGNUM *bn){    heim_integer *hi = (heim_integer *)bn;    if (hi->data) {	memset(hi->data, 0, hi->length);	free(hi->data);    }    memset(hi, 0, sizeof(*hi));}voidBN_clear_free(BIGNUM *bn){    BN_free(bn);}BIGNUM *BN_dup(const BIGNUM *bn){    BIGNUM *b = BN_new();    if (der_copy_heim_integer((const heim_integer *)bn, (heim_integer *)b)) {	BN_free(b);	return NULL;    }    return b;}/* * If the caller really want to know the number of bits used, subtract * one from the length, multiply by 8, and then lookup in the table * how many bits the hightest byte uses. */intBN_num_bits(const BIGNUM *bn){    static unsigned char num2bits[256] = {	0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,	6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,    };    const heim_integer *i = (const void *)bn;    if (i->length == 0)	return 0;    return (i->length - 1) * 8 + num2bits[((unsigned char *)i->data)[0]];}intBN_num_bytes(const BIGNUM *bn){    return ((const heim_integer *)bn)->length;}/* * Ignore negative flag. */BIGNUM *BN_bin2bn(const void *s, int len, BIGNUM *bn){    heim_integer *hi = (void *)bn;    if (len < 0)	return NULL;    if (hi == NULL) {	hi = (heim_integer *)BN_new();	if (hi == NULL)	    return NULL;    }    if (hi->data)	BN_clear((BIGNUM *)hi);    hi->negative = 0;    hi->data = malloc(len);    if (hi->data == NULL && len != 0) {	if (bn == NULL)	    BN_free((BIGNUM *)hi);	return NULL;    }    hi->length = len;    memcpy(hi->data, s, len);    return (BIGNUM *)hi;}intBN_bn2bin(const BIGNUM *bn, void *to){    const heim_integer *hi = (const void *)bn;    memcpy(to, hi->data, hi->length);    return hi->length;}intBN_hex2bn(BIGNUM **bnp, const char *in){    int negative;    ssize_t ret;    size_t len;    void *data;    len = strlen(in);    data = malloc(len);    if (data == NULL)	return 0;    if (*in == '-') {	negative = 1;	in++;    } else	negative = 0;    ret = hex_decode(in, data, len);    if (ret < 0) {	free(data);	return 0;    }    *bnp = BN_bin2bn(data, ret, NULL);    free(data);    if (*bnp == NULL)	return 0;    BN_set_negative(*bnp, negative);    return 1;}char *BN_bn2hex(const BIGNUM *bn){    ssize_t ret;    size_t len;    void *data;    char *str;    len = BN_num_bytes(bn);    data = malloc(len);    if (data == NULL)	return 0;    len = BN_bn2bin(bn, data);    ret = hex_encode(data, len, &str);    free(data);    if (ret < 0)	return 0;    return str;}intBN_cmp(const BIGNUM *bn1, const BIGNUM *bn2){    return der_heim_integer_cmp((const heim_integer *)bn1, 				(const heim_integer *)bn2);}voidBN_set_negative(BIGNUM *bn, int flag){    ((heim_integer *)bn)->negative = (flag ? 1 : 0);}intBN_is_negative(const BIGNUM *bn){    return ((const heim_integer *)bn)->negative ? 1 : 0;}static const unsigned char is_set[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };intBN_is_bit_set(const BIGNUM *bn, int bit){    heim_integer *hi = (heim_integer *)bn;    unsigned char *p = hi->data;    if ((bit / 8) > hi->length || hi->length == 0)	return 0;        return p[hi->length - 1 - (bit / 8)] & is_set[bit % 8];}intBN_set_bit(BIGNUM *bn, int bit){    heim_integer *hi = (heim_integer *)bn;    unsigned char *p;    if ((bit / 8) > hi->length || hi->length == 0) {	size_t len = (bit + 7) / 8;	void *d = realloc(hi->data, len);	if (d == NULL)	    return 0;	hi->data = d;	p = hi->data;	memset(&p[hi->length], 0, len);	hi->length = len;    } else	p = hi->data;    p[hi->length - 1 - (bit / 8)] |= is_set[bit % 8];    return 1;}intBN_clear_bit(BIGNUM *bn, int bit){    heim_integer *hi = (heim_integer *)bn;    unsigned char *p = hi->data;    if ((bit / 8) > hi->length || hi->length == 0)	return 0;    p[hi->length - 1 - (bit / 8)] &= (unsigned char)(~(is_set[bit % 8]));    return 1;}intBN_set_word(BIGNUM *bn, unsigned long num){    unsigned char p[sizeof(num)];    unsigned long num2;    int i, len;    for (num2 = num, i = 0; num2 > 0; i++)	num2 = num2 >> 8;    len = i - 1;    for (; i > 0; i--) {	p[i - 1] = (num & 0xff);	num = num >> 8;    }    bn = BN_bin2bn(p, len + 1, bn);    return bn != NULL;}unsigned longBN_get_word(const BIGNUM *bn){    heim_integer *hi = (heim_integer *)bn;    unsigned long num = 0;    int i;    if (hi->negative || hi->length > sizeof(num))	return ULONG_MAX;    for (i = 0; i < hi->length; i++)	num = ((unsigned char *)hi->data)[i] | (num << 8);    return num;}intBN_rand(BIGNUM *bn, int bits, int top, int bottom){    size_t len = (bits + 7) / 8;    heim_integer *i = (heim_integer *)bn;    BN_clear(bn);    i->negative = 0;    i->data = malloc(len);    if (i->data == NULL && len != 0)	return 0;    i->length = len;    if (RAND_bytes(i->data, i->length) != 1) {	free(i->data);	i->data = NULL;	return 0;    }    {	size_t j = len * 8;	while(j > bits) {	    BN_clear_bit(bn, j - 1);	    j--;	}    }    if (top == -1) {	;    } else if (top == 0 && bits > 0) {	BN_set_bit(bn, bits - 1);    } else if (top == 1 && bits > 1) {	BN_set_bit(bn, bits - 1);	BN_set_bit(bn, bits - 2);    } else {	BN_clear(bn);	return 0;    }    if (bottom && bits > 0)	BN_set_bit(bn, 0);    return 1;}/* * */intBN_uadd(BIGNUM *res, const BIGNUM *a, const BIGNUM *b){    const heim_integer *ai = (const heim_integer *)a;    const heim_integer *bi = (const heim_integer *)b;    const unsigned char *ap, *bp;    unsigned char *cp;    heim_integer ci;    int carry = 0;    ssize_t len;    if (ai->negative && bi->negative)	return 0;    if (ai->length < bi->length) {	const heim_integer *si = bi;	bi = ai; ai = si;    }        ci.negative = 0;    ci.length = ai->length + 1;    ci.data = malloc(ci.length);    if (ci.data == NULL)	return 0;    ap = &((const unsigned char *)ai->data)[ai->length - 1];    bp = &((const unsigned char *)bi->data)[bi->length - 1];    cp = &((unsigned char *)ci.data)[ci.length - 1];    for (len = bi->length; len > 0; len--) {	carry = *ap + *bp + carry;	*cp = carry & 0xff;	carry = (carry & ~0xff) ? 1 : 0;	ap--; bp--; cp--;    }    for (len = ai->length - bi->length; len > 0; len--) {	carry = *ap + carry;	*cp = carry & 0xff;	carry = (carry & ~0xff) ? 1 : 0;	ap--; cp--;    }    if (!carry)	memmove(cp, cp + 1, --ci.length);    else	*cp = carry;        BN_clear(res);    *((heim_integer *)res) = ci;    return 1;}/* * Callback when doing slow generation of numbers, like primes. */voidBN_GENCB_set(BN_GENCB *gencb, int (*cb_2)(int, int, BN_GENCB *), void *ctx){    gencb->ver = 2;    gencb->cb.cb_2 = cb_2;    gencb->arg = ctx;}intBN_GENCB_call(BN_GENCB *cb, int a, int b){    if (cb == NULL || cb->cb.cb_2 == NULL)	return 1;    return cb->cb.cb_2(a, b, cb);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -