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

📄 dh.c

📁 samba最新软件
💻 C
字号:
/* * Copyright (c) 2006 - 2007 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: dh.c 22397 2008-01-01 20:20:31Z lha $");#include <stdio.h>#include <stdlib.h>#include <dh.h>#include <roken.h>/** * @page page_dh DH - Diffie-Hellman key exchange * * Diffie-Hellman key exchange is a protocol that allows two parties * to establish a shared secret key. * * Include and example how to use DH_new() and friends here. * * See the library functions here: @ref hcrypto_dh *//** * Create a new DH object using DH_new_method(NULL), see DH_new_method(). * * @return a newly allocated DH object. * * @ingroup hcrypto_dh */DH *DH_new(void){    return DH_new_method(NULL);}/** * Create a new DH object from the given engine, if the NULL is used, * the default engine is used. Free the DH object with DH_free(). * * @param engine The engine to use to allocate the DH object.  * * @return a newly allocated DH object. * * @ingroup hcrypto_dh */DH *DH_new_method(ENGINE *engine){    DH *dh;    dh = calloc(1, sizeof(*dh));    if (dh == NULL)	return NULL;    dh->references = 1;    if (engine) {	ENGINE_up_ref(engine);	dh->engine = engine;    } else {	dh->engine = ENGINE_get_default_DH();    }    if (dh->engine) {	dh->meth = ENGINE_get_DH(dh->engine);	if (dh->meth == NULL) {	    ENGINE_finish(engine);	    free(dh);	    return 0;	}    }    if (dh->meth == NULL)	dh->meth = DH_get_default_method();    (*dh->meth->init)(dh);    return dh;}/** * Free a DH object and release related resources, like ENGINE, that * the object was using. * * @param dh object to be freed. * * @ingroup hcrypto_dh */voidDH_free(DH *dh){    if (dh->references <= 0)	abort();    if (--dh->references > 0)	return;    (*dh->meth->finish)(dh);    if (dh->engine)	ENGINE_finish(dh->engine);#define free_if(f) if (f) { BN_free(f); }    free_if(dh->p);    free_if(dh->g);    free_if(dh->pub_key);    free_if(dh->priv_key);    free_if(dh->q);    free_if(dh->j);    free_if(dh->counter);#undef free_if    memset(dh, 0, sizeof(*dh));    free(dh);}    /** * Add a reference to the DH object. The object should be free with * DH_free() to drop the reference. * * @param dh the object to increase the reference count too. * * @return the updated reference count, can't safely be used except * for debug printing. *  * @ingroup hcrypto_dh */intDH_up_ref(DH *dh){    return ++dh->references;}/** * The maximum output size of the DH_compute_key() function. * * @param dh The DH object to get the size from. * * @return the maximum size in bytes of the out data. * * @ingroup hcrypto_dh */intDH_size(const DH *dh){    return BN_num_bytes(dh->p);}/** * Set the data index idx in the DH object to data. * * @param dh DH object. * @param idx index to set the data for. * @param data data to store for the index idx. * * @return 1 on success. * * @ingroup hcrypto_dh */intDH_set_ex_data(DH *dh, int idx, void *data){    dh->ex_data.sk = data;    return 1;}/** * Get the data for index idx in the DH object. * * @param dh DH object. * @param idx index to get the data for. * * @return the object store in index idx * * @ingroup hcrypto_dh */void *DH_get_ex_data(DH *dh, int idx){    return dh->ex_data.sk;}/** * Generate DH parameters for the DH object give parameters. * * @param dh The DH object to generate parameters for. * @param prime_len length of the prime * @param generator generator, g * @param cb Callback parameters to show progress, can be NULL. * * @return the maximum size in bytes of the out data. * * @ingroup hcrypto_dh */intDH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb){    if (dh->meth->generate_params)	return dh->meth->generate_params(dh, prime_len, generator, cb);    return 0;}/** * Check that the public key is sane. * * @param dh the local peer DH parameters. * @param pub_key the remote peer public key parameters. * @param codes return that the failures of the pub_key are. * * @return 1 on success, 0 on failure and *codes is set the the * combined fail check for the public key * * @ingroup hcrypto_dh */intDH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes){    BIGNUM *bn = NULL, *sum = NULL;    int ret = 0;    *codes = 0;    /**     * Checks that the function performs are:     * - pub_key is not negative      */    if (BN_is_negative(pub_key))	goto out;    /**     * - pub_key > 1    and    pub_key < p - 1,     *    to avoid small subgroups attack.     */    bn = BN_new();    if (bn == NULL)	goto out;    if (!BN_set_word(bn, 1))	goto out;    if (BN_cmp(bn, pub_key) >= 0)	*codes |= DH_CHECK_PUBKEY_TOO_SMALL;    sum = BN_new();    if (sum == NULL)	goto out;    BN_uadd(sum, pub_key, bn);    if (BN_cmp(sum, dh->p) >= 0)	*codes |= DH_CHECK_PUBKEY_TOO_LARGE;    /**     * - if g == 2, pub_key have more then one bit set,     *   if bits set is 1, log_2(pub_key) is trival     */    if (!BN_set_word(bn, 2))	goto out;    if (BN_cmp(bn, pub_key) == 0) {	unsigned i, n = BN_num_bits(pub_key);	unsigned bits = 0;	for (i = 0; i <= n; i++)	    if (BN_is_bit_set(pub_key, i))		bits++;	if (bits > 1) {	    *codes |= DH_CHECK_PUBKEY_TOO_SMALL;	    goto out;	}    }    ret = 1;out:    if (bn)	BN_free(bn);    if (sum)	BN_free(sum);    return ret;}/** * Generate a new DH private-public key pair. The dh parameter must be * allocted first with DH_new(). dh->p and dp->g must be set. * * @param dh dh parameter. * * @return 1 on success. * * @ingroup hcrypto_dh */intDH_generate_key(DH *dh){    return dh->meth->generate_key(dh);}/** * Complute the shared secret key. * * @param shared_key the resulting shared key, need to be at least * DH_size() large. * @param peer_pub_key the peer's public key. * @param dh the dh key pair. * * @return 1 on success. * * @ingroup hcrypto_dh */intDH_compute_key(unsigned char *shared_key,	       const BIGNUM *peer_pub_key, DH *dh){    int codes;    /**     * Checks that the pubkey passed in is valid using     * DH_check_pubkey().     */    if (!DH_check_pubkey(dh, peer_pub_key, &codes) || codes != 0)	return -1;    return dh->meth->compute_key(shared_key, peer_pub_key, dh);}/** * Set a new method for the DH keypair. * * @param dh dh parameter. * @param method the new method for the DH parameter. * * @return 1 on success. * * @ingroup hcrypto_dh */intDH_set_method(DH *dh, const DH_METHOD *method){    (*dh->meth->finish)(dh);    if (dh->engine) {	ENGINE_finish(dh->engine);	dh->engine = NULL;    }    dh->meth = method;    (*dh->meth->init)(dh);    return 1;}/* * */static intdh_null_generate_key(DH *dh){    return 0;}static intdh_null_compute_key(unsigned char *shared,const BIGNUM *pub, DH *dh){    return 0;}static intdh_null_init(DH *dh){    return 1;}static intdh_null_finish(DH *dh){    return 1;}static intdh_null_generate_params(DH *dh, int prime_num, int len, BN_GENCB *cb){    return 0;}static const DH_METHOD dh_null_method = {    "hcrypto null DH",    dh_null_generate_key,    dh_null_compute_key,    NULL,    dh_null_init,    dh_null_finish,    0,    NULL,    dh_null_generate_params};extern const DH_METHOD _hc_dh_imath_method;static const DH_METHOD *dh_default_method = &_hc_dh_imath_method;/** * Return the dummy DH implementation. * * @return pointer to a DH_METHOD. * * @ingroup hcrypto_dh */const DH_METHOD *DH_null_method(void){    return &dh_null_method;}/** * Set the default DH implementation. * * @param meth pointer to a DH_METHOD. * * @ingroup hcrypto_dh */voidDH_set_default_method(const DH_METHOD *meth){    dh_default_method = meth;}/** * Return the default DH implementation. * * @return pointer to a DH_METHOD. * * @ingroup hcrypto_dh */const DH_METHOD *DH_get_default_method(void){    return dh_default_method;}

⌨️ 快捷键说明

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