Home | History | Annotate | Line # | Download | only in hcrypto
dh.c revision 1.2.22.1
      1  1.2.22.1    martin /*	$NetBSD: dh.c,v 1.2.22.1 2023/08/11 13:39:58 martin Exp $	*/
      2       1.1     elric 
      3       1.1     elric /*
      4       1.1     elric  * Copyright (c) 2006 - 2007 Kungliga Tekniska Hgskolan
      5       1.1     elric  * (Royal Institute of Technology, Stockholm, Sweden).
      6       1.1     elric  * All rights reserved.
      7       1.1     elric  *
      8       1.1     elric  * Redistribution and use in source and binary forms, with or without
      9       1.1     elric  * modification, are permitted provided that the following conditions
     10       1.1     elric  * are met:
     11       1.1     elric  *
     12       1.1     elric  * 1. Redistributions of source code must retain the above copyright
     13       1.1     elric  *    notice, this list of conditions and the following disclaimer.
     14       1.1     elric  *
     15       1.1     elric  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1     elric  *    notice, this list of conditions and the following disclaimer in the
     17       1.1     elric  *    documentation and/or other materials provided with the distribution.
     18       1.1     elric  *
     19       1.1     elric  * 3. Neither the name of the Institute nor the names of its contributors
     20       1.1     elric  *    may be used to endorse or promote products derived from this software
     21       1.1     elric  *    without specific prior written permission.
     22       1.1     elric  *
     23       1.1     elric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24       1.1     elric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25       1.1     elric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26       1.1     elric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27       1.1     elric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28       1.1     elric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29       1.1     elric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30       1.1     elric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31       1.1     elric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32       1.1     elric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33       1.1     elric  * SUCH DAMAGE.
     34       1.1     elric  */
     35       1.1     elric 
     36       1.1     elric #ifdef HAVE_CONFIG_H
     37       1.1     elric #include <config.h>
     38       1.1     elric #endif
     39       1.2  christos #include <krb5/roken.h>
     40       1.1     elric 
     41       1.1     elric #include <krb5/krb5-types.h>
     42       1.1     elric #include <krb5/rfc2459_asn1.h>
     43       1.1     elric 
     44       1.1     elric #include <dh.h>
     45       1.1     elric 
     46       1.1     elric /**
     47       1.1     elric  * @page page_dh DH - Diffie-Hellman key exchange
     48       1.1     elric  *
     49       1.1     elric  * Diffie-Hellman key exchange is a protocol that allows two parties
     50       1.1     elric  * to establish a shared secret key.
     51       1.1     elric  *
     52       1.1     elric  * Include and example how to use DH_new() and friends here.
     53       1.1     elric  *
     54       1.1     elric  * See the library functions here: @ref hcrypto_dh
     55       1.1     elric  */
     56       1.1     elric 
     57       1.1     elric /**
     58       1.1     elric  * Create a new DH object using DH_new_method(NULL), see DH_new_method().
     59       1.1     elric  *
     60       1.1     elric  * @return a newly allocated DH object.
     61       1.1     elric  *
     62       1.1     elric  * @ingroup hcrypto_dh
     63       1.1     elric  */
     64       1.1     elric 
     65       1.1     elric DH *
     66       1.1     elric DH_new(void)
     67       1.1     elric {
     68       1.1     elric     return DH_new_method(NULL);
     69       1.1     elric }
     70       1.1     elric 
     71       1.1     elric /**
     72       1.1     elric  * Create a new DH object from the given engine, if the NULL is used,
     73       1.1     elric  * the default engine is used. Free the DH object with DH_free().
     74       1.1     elric  *
     75       1.1     elric  * @param engine The engine to use to allocate the DH object.
     76       1.1     elric  *
     77       1.1     elric  * @return a newly allocated DH object.
     78       1.1     elric  *
     79       1.1     elric  * @ingroup hcrypto_dh
     80       1.1     elric  */
     81       1.1     elric 
     82       1.1     elric DH *
     83       1.1     elric DH_new_method(ENGINE *engine)
     84       1.1     elric {
     85       1.1     elric     DH *dh;
     86       1.1     elric 
     87       1.1     elric     dh = calloc(1, sizeof(*dh));
     88       1.1     elric     if (dh == NULL)
     89       1.1     elric 	return NULL;
     90       1.1     elric 
     91       1.1     elric     dh->references = 1;
     92       1.1     elric 
     93       1.1     elric     if (engine) {
     94       1.1     elric 	ENGINE_up_ref(engine);
     95       1.1     elric 	dh->engine = engine;
     96       1.1     elric     } else {
     97       1.1     elric 	dh->engine = ENGINE_get_default_DH();
     98       1.1     elric     }
     99       1.1     elric 
    100       1.1     elric     if (dh->engine) {
    101       1.1     elric 	dh->meth = ENGINE_get_DH(dh->engine);
    102       1.1     elric 	if (dh->meth == NULL) {
    103       1.1     elric 	    ENGINE_finish(engine);
    104       1.1     elric 	    free(dh);
    105       1.1     elric 	    return 0;
    106       1.1     elric 	}
    107       1.1     elric     }
    108       1.1     elric 
    109       1.1     elric     if (dh->meth == NULL)
    110       1.1     elric 	dh->meth = DH_get_default_method();
    111       1.1     elric 
    112       1.1     elric     (*dh->meth->init)(dh);
    113       1.1     elric 
    114       1.1     elric     return dh;
    115       1.1     elric }
    116       1.1     elric 
    117       1.1     elric /**
    118       1.1     elric  * Free a DH object and release related resources, like ENGINE, that
    119       1.1     elric  * the object was using.
    120       1.1     elric  *
    121       1.1     elric  * @param dh object to be freed.
    122       1.1     elric  *
    123       1.1     elric  * @ingroup hcrypto_dh
    124       1.1     elric  */
    125       1.1     elric 
    126       1.1     elric void
    127       1.1     elric DH_free(DH *dh)
    128       1.1     elric {
    129       1.1     elric     if (dh->references <= 0)
    130       1.1     elric 	abort();
    131       1.1     elric 
    132       1.1     elric     if (--dh->references > 0)
    133       1.1     elric 	return;
    134       1.1     elric 
    135       1.1     elric     (*dh->meth->finish)(dh);
    136       1.1     elric 
    137       1.1     elric     if (dh->engine)
    138       1.1     elric 	ENGINE_finish(dh->engine);
    139       1.1     elric 
    140       1.1     elric #define free_if(f) if (f) { BN_free(f); }
    141       1.1     elric     free_if(dh->p);
    142       1.1     elric     free_if(dh->g);
    143       1.1     elric     free_if(dh->pub_key);
    144       1.1     elric     free_if(dh->priv_key);
    145       1.1     elric     free_if(dh->q);
    146       1.1     elric     free_if(dh->j);
    147       1.1     elric     free_if(dh->counter);
    148       1.1     elric #undef free_if
    149       1.1     elric 
    150       1.1     elric     memset(dh, 0, sizeof(*dh));
    151       1.1     elric     free(dh);
    152       1.1     elric }
    153       1.1     elric 
    154       1.1     elric /**
    155       1.1     elric  * Add a reference to the DH object. The object should be free with
    156       1.1     elric  * DH_free() to drop the reference.
    157       1.1     elric  *
    158       1.1     elric  * @param dh the object to increase the reference count too.
    159       1.1     elric  *
    160       1.1     elric  * @return the updated reference count, can't safely be used except
    161       1.1     elric  * for debug printing.
    162       1.1     elric  *
    163       1.1     elric  * @ingroup hcrypto_dh
    164       1.1     elric  */
    165       1.1     elric 
    166       1.1     elric int
    167       1.1     elric DH_up_ref(DH *dh)
    168       1.1     elric {
    169       1.1     elric     return ++dh->references;
    170       1.1     elric }
    171       1.1     elric 
    172       1.1     elric /**
    173       1.1     elric  * The maximum output size of the DH_compute_key() function.
    174       1.1     elric  *
    175       1.1     elric  * @param dh The DH object to get the size from.
    176       1.1     elric  *
    177       1.1     elric  * @return the maximum size in bytes of the out data.
    178       1.1     elric  *
    179       1.1     elric  * @ingroup hcrypto_dh
    180       1.1     elric  */
    181       1.1     elric 
    182       1.1     elric int
    183       1.1     elric DH_size(const DH *dh)
    184       1.1     elric {
    185       1.1     elric     return BN_num_bytes(dh->p);
    186       1.1     elric }
    187       1.1     elric 
    188       1.1     elric /**
    189       1.1     elric  * Set the data index idx in the DH object to data.
    190       1.1     elric  *
    191       1.1     elric  * @param dh DH object.
    192       1.1     elric  * @param idx index to set the data for.
    193       1.1     elric  * @param data data to store for the index idx.
    194       1.1     elric  *
    195       1.1     elric  * @return 1 on success.
    196       1.1     elric  *
    197       1.1     elric  * @ingroup hcrypto_dh
    198       1.1     elric  */
    199       1.1     elric 
    200       1.1     elric int
    201       1.1     elric DH_set_ex_data(DH *dh, int idx, void *data)
    202       1.1     elric {
    203       1.1     elric     dh->ex_data.sk = data;
    204       1.1     elric     return 1;
    205       1.1     elric }
    206       1.1     elric 
    207       1.1     elric /**
    208       1.1     elric  * Get the data for index idx in the DH object.
    209       1.1     elric  *
    210       1.1     elric  * @param dh DH object.
    211       1.1     elric  * @param idx index to get the data for.
    212       1.1     elric  *
    213       1.1     elric  * @return the object store in index idx
    214       1.1     elric  *
    215       1.1     elric  * @ingroup hcrypto_dh
    216       1.1     elric  */
    217       1.1     elric 
    218       1.1     elric void *
    219       1.1     elric DH_get_ex_data(DH *dh, int idx)
    220       1.1     elric {
    221       1.1     elric     return dh->ex_data.sk;
    222       1.1     elric }
    223       1.1     elric 
    224       1.1     elric /**
    225       1.1     elric  * Generate DH parameters for the DH object give parameters.
    226       1.1     elric  *
    227       1.1     elric  * @param dh The DH object to generate parameters for.
    228       1.1     elric  * @param prime_len length of the prime
    229       1.1     elric  * @param generator generator, g
    230       1.1     elric  * @param cb Callback parameters to show progress, can be NULL.
    231       1.1     elric  *
    232       1.1     elric  * @return the maximum size in bytes of the out data.
    233       1.1     elric  *
    234       1.1     elric  * @ingroup hcrypto_dh
    235       1.1     elric  */
    236       1.1     elric 
    237       1.1     elric int
    238       1.1     elric DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb)
    239       1.1     elric {
    240       1.1     elric     if (dh->meth->generate_params)
    241       1.1     elric 	return dh->meth->generate_params(dh, prime_len, generator, cb);
    242       1.1     elric     return 0;
    243       1.1     elric }
    244       1.1     elric 
    245       1.1     elric /**
    246       1.1     elric  * Check that the public key is sane.
    247       1.1     elric  *
    248       1.1     elric  * @param dh the local peer DH parameters.
    249       1.1     elric  * @param pub_key the remote peer public key parameters.
    250       1.1     elric  * @param codes return that the failures of the pub_key are.
    251       1.1     elric  *
    252       1.1     elric  * @return 1 on success, 0 on failure and *codes is set the the
    253       1.1     elric  * combined fail check for the public key
    254       1.1     elric  *
    255       1.1     elric  * @ingroup hcrypto_dh
    256       1.1     elric  */
    257       1.1     elric 
    258       1.1     elric int
    259       1.1     elric DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes)
    260       1.1     elric {
    261       1.1     elric     BIGNUM *bn = NULL, *sum = NULL;
    262       1.1     elric     int ret = 0;
    263       1.1     elric 
    264       1.1     elric     *codes = 0;
    265       1.1     elric 
    266       1.1     elric     /**
    267       1.1     elric      * Checks that the function performs are:
    268       1.1     elric      * - pub_key is not negative
    269       1.1     elric      */
    270       1.1     elric 
    271       1.1     elric     if (BN_is_negative(pub_key))
    272       1.1     elric 	goto out;
    273       1.1     elric 
    274       1.1     elric     /**
    275       1.1     elric      * - pub_key > 1    and    pub_key < p - 1,
    276       1.1     elric      *    to avoid small subgroups attack.
    277       1.1     elric      */
    278       1.1     elric 
    279       1.1     elric     bn = BN_new();
    280       1.1     elric     if (bn == NULL)
    281       1.1     elric 	goto out;
    282       1.1     elric 
    283       1.1     elric     if (!BN_set_word(bn, 1))
    284       1.1     elric 	goto out;
    285       1.1     elric 
    286       1.1     elric     if (BN_cmp(bn, pub_key) >= 0)
    287       1.1     elric 	*codes |= DH_CHECK_PUBKEY_TOO_SMALL;
    288       1.1     elric 
    289       1.1     elric     sum = BN_new();
    290       1.1     elric     if (sum == NULL)
    291       1.1     elric 	goto out;
    292       1.1     elric 
    293       1.1     elric     BN_uadd(sum, pub_key, bn);
    294       1.1     elric 
    295       1.1     elric     if (BN_cmp(sum, dh->p) >= 0)
    296       1.1     elric 	*codes |= DH_CHECK_PUBKEY_TOO_LARGE;
    297       1.1     elric 
    298       1.1     elric     /**
    299       1.1     elric      * - if g == 2, pub_key have more then one bit set,
    300       1.1     elric      *   if bits set is 1, log_2(pub_key) is trival
    301       1.1     elric      */
    302       1.1     elric 
    303       1.1     elric     if (!BN_set_word(bn, 2))
    304       1.1     elric 	goto out;
    305       1.1     elric 
    306       1.1     elric     if (BN_cmp(bn, dh->g) == 0) {
    307       1.1     elric 	unsigned i, n = BN_num_bits(pub_key);
    308       1.1     elric 	unsigned bits = 0;
    309       1.1     elric 
    310  1.2.22.1    martin 	for (i = 0; i < n; i++)
    311       1.1     elric 	    if (BN_is_bit_set(pub_key, i))
    312       1.1     elric 		bits++;
    313       1.1     elric 
    314       1.1     elric 	if (bits < 2) {
    315       1.1     elric 	    *codes |= DH_CHECK_PUBKEY_TOO_SMALL;
    316       1.1     elric 	    goto out;
    317       1.1     elric 	}
    318       1.1     elric     }
    319       1.1     elric 
    320       1.1     elric     ret = 1;
    321       1.1     elric out:
    322       1.1     elric     if (bn)
    323       1.1     elric 	BN_free(bn);
    324       1.1     elric     if (sum)
    325       1.1     elric 	BN_free(sum);
    326       1.1     elric 
    327       1.1     elric     return ret;
    328       1.1     elric }
    329       1.1     elric 
    330       1.1     elric /**
    331       1.1     elric  * Generate a new DH private-public key pair. The dh parameter must be
    332       1.1     elric  * allocted first with DH_new(). dh->p and dp->g must be set.
    333       1.1     elric  *
    334       1.1     elric  * @param dh dh parameter.
    335       1.1     elric  *
    336       1.1     elric  * @return 1 on success.
    337       1.1     elric  *
    338       1.1     elric  * @ingroup hcrypto_dh
    339       1.1     elric  */
    340       1.1     elric 
    341       1.1     elric int
    342       1.1     elric DH_generate_key(DH *dh)
    343       1.1     elric {
    344       1.1     elric     return dh->meth->generate_key(dh);
    345       1.1     elric }
    346       1.1     elric 
    347       1.1     elric /**
    348       1.1     elric  * Complute the shared secret key.
    349       1.1     elric  *
    350       1.1     elric  * @param shared_key the resulting shared key, need to be at least
    351       1.1     elric  * DH_size() large.
    352       1.1     elric  * @param peer_pub_key the peer's public key.
    353       1.1     elric  * @param dh the dh key pair.
    354       1.1     elric  *
    355       1.1     elric  * @return 1 on success.
    356       1.1     elric  *
    357       1.1     elric  * @ingroup hcrypto_dh
    358       1.1     elric  */
    359       1.1     elric 
    360       1.1     elric int
    361       1.1     elric DH_compute_key(unsigned char *shared_key,
    362       1.1     elric 	       const BIGNUM *peer_pub_key, DH *dh)
    363       1.1     elric {
    364       1.1     elric     int codes;
    365       1.1     elric 
    366       1.1     elric     /**
    367       1.1     elric      * Checks that the pubkey passed in is valid using
    368       1.1     elric      * DH_check_pubkey().
    369       1.1     elric      */
    370       1.1     elric 
    371       1.1     elric     if (!DH_check_pubkey(dh, peer_pub_key, &codes) || codes != 0)
    372       1.1     elric 	return -1;
    373       1.1     elric 
    374       1.1     elric     return dh->meth->compute_key(shared_key, peer_pub_key, dh);
    375       1.1     elric }
    376       1.1     elric 
    377       1.1     elric /**
    378       1.1     elric  * Set a new method for the DH keypair.
    379       1.1     elric  *
    380       1.1     elric  * @param dh dh parameter.
    381       1.1     elric  * @param method the new method for the DH parameter.
    382       1.1     elric  *
    383       1.1     elric  * @return 1 on success.
    384       1.1     elric  *
    385       1.1     elric  * @ingroup hcrypto_dh
    386       1.1     elric  */
    387       1.1     elric 
    388       1.1     elric int
    389       1.1     elric DH_set_method(DH *dh, const DH_METHOD *method)
    390       1.1     elric {
    391       1.1     elric     (*dh->meth->finish)(dh);
    392       1.1     elric     if (dh->engine) {
    393       1.1     elric 	ENGINE_finish(dh->engine);
    394       1.1     elric 	dh->engine = NULL;
    395       1.1     elric     }
    396       1.1     elric     dh->meth = method;
    397       1.1     elric     (*dh->meth->init)(dh);
    398       1.1     elric     return 1;
    399       1.1     elric }
    400       1.1     elric 
    401       1.1     elric /*
    402       1.1     elric  *
    403       1.1     elric  */
    404       1.1     elric 
    405       1.1     elric static int
    406       1.1     elric dh_null_generate_key(DH *dh)
    407       1.1     elric {
    408       1.1     elric     return 0;
    409       1.1     elric }
    410       1.1     elric 
    411       1.1     elric static int
    412       1.1     elric dh_null_compute_key(unsigned char *shared,const BIGNUM *pub, DH *dh)
    413       1.1     elric {
    414       1.1     elric     return 0;
    415       1.1     elric }
    416       1.1     elric 
    417       1.1     elric static int
    418       1.1     elric dh_null_init(DH *dh)
    419       1.1     elric {
    420       1.1     elric     return 1;
    421       1.1     elric }
    422       1.1     elric 
    423       1.1     elric static int
    424       1.1     elric dh_null_finish(DH *dh)
    425       1.1     elric {
    426       1.1     elric     return 1;
    427       1.1     elric }
    428       1.1     elric 
    429       1.1     elric static int
    430       1.1     elric dh_null_generate_params(DH *dh, int prime_num, int len, BN_GENCB *cb)
    431       1.1     elric {
    432       1.1     elric     return 0;
    433       1.1     elric }
    434       1.1     elric 
    435       1.1     elric static const DH_METHOD dh_null_method = {
    436       1.1     elric     "hcrypto null DH",
    437       1.1     elric     dh_null_generate_key,
    438       1.1     elric     dh_null_compute_key,
    439       1.1     elric     NULL,
    440       1.1     elric     dh_null_init,
    441       1.1     elric     dh_null_finish,
    442       1.1     elric     0,
    443       1.1     elric     NULL,
    444       1.1     elric     dh_null_generate_params
    445       1.1     elric };
    446       1.1     elric 
    447       1.1     elric extern const DH_METHOD _hc_dh_ltm_method;
    448       1.1     elric static const DH_METHOD *dh_default_method = &_hc_dh_ltm_method;
    449       1.1     elric 
    450       1.1     elric /**
    451       1.1     elric  * Return the dummy DH implementation.
    452       1.1     elric  *
    453       1.1     elric  * @return pointer to a DH_METHOD.
    454       1.1     elric  *
    455       1.1     elric  * @ingroup hcrypto_dh
    456       1.1     elric  */
    457       1.1     elric 
    458       1.1     elric const DH_METHOD *
    459       1.1     elric DH_null_method(void)
    460       1.1     elric {
    461       1.1     elric     return &dh_null_method;
    462       1.1     elric }
    463       1.1     elric 
    464       1.1     elric /**
    465       1.1     elric  * Set the default DH implementation.
    466       1.1     elric  *
    467       1.1     elric  * @param meth pointer to a DH_METHOD.
    468       1.1     elric  *
    469       1.1     elric  * @ingroup hcrypto_dh
    470       1.1     elric  */
    471       1.1     elric 
    472       1.1     elric void
    473       1.1     elric DH_set_default_method(const DH_METHOD *meth)
    474       1.1     elric {
    475       1.1     elric     dh_default_method = meth;
    476       1.1     elric }
    477       1.1     elric 
    478       1.1     elric /**
    479       1.1     elric  * Return the default DH implementation.
    480       1.1     elric  *
    481       1.1     elric  * @return pointer to a DH_METHOD.
    482       1.1     elric  *
    483       1.1     elric  * @ingroup hcrypto_dh
    484       1.1     elric  */
    485       1.1     elric 
    486       1.1     elric const DH_METHOD *
    487       1.1     elric DH_get_default_method(void)
    488       1.1     elric {
    489       1.1     elric     return dh_default_method;
    490       1.1     elric }
    491       1.1     elric 
    492       1.1     elric /*
    493       1.1     elric  *
    494       1.1     elric  */
    495       1.1     elric 
    496       1.1     elric static int
    497       1.1     elric bn2heim_int(BIGNUM *bn, heim_integer *integer)
    498       1.1     elric {
    499       1.1     elric     integer->length = BN_num_bytes(bn);
    500       1.1     elric     integer->data = malloc(integer->length);
    501       1.1     elric     if (integer->data == NULL) {
    502       1.1     elric 	integer->length = 0;
    503       1.1     elric 	return ENOMEM;
    504       1.1     elric     }
    505       1.1     elric     BN_bn2bin(bn, integer->data);
    506       1.1     elric     integer->negative = BN_is_negative(bn);
    507       1.1     elric     return 0;
    508       1.1     elric }
    509       1.1     elric 
    510       1.1     elric /**
    511       1.1     elric  *
    512       1.1     elric  */
    513       1.1     elric 
    514       1.1     elric int
    515       1.1     elric i2d_DHparams(DH *dh, unsigned char **pp)
    516       1.1     elric {
    517       1.1     elric     DHParameter data;
    518       1.1     elric     size_t size;
    519       1.1     elric     int ret;
    520       1.1     elric 
    521       1.1     elric     memset(&data, 0, sizeof(data));
    522       1.1     elric 
    523       1.1     elric     if (bn2heim_int(dh->p, &data.prime) ||
    524       1.1     elric 	bn2heim_int(dh->g, &data.base))
    525       1.1     elric     {
    526       1.1     elric 	free_DHParameter(&data);
    527       1.1     elric 	return -1;
    528       1.1     elric     }
    529       1.1     elric 
    530       1.1     elric     if (pp == NULL) {
    531       1.1     elric 	size = length_DHParameter(&data);
    532       1.1     elric 	free_DHParameter(&data);
    533       1.1     elric     } else {
    534       1.1     elric 	void *p;
    535       1.1     elric 	size_t len;
    536       1.1     elric 
    537       1.1     elric 	ASN1_MALLOC_ENCODE(DHParameter, p, len, &data, &size, ret);
    538       1.1     elric 	free_DHParameter(&data);
    539       1.1     elric 	if (ret)
    540       1.1     elric 	    return -1;
    541       1.2  christos 	if (len != size) {
    542       1.1     elric 	    abort();
    543       1.2  christos             return -1;
    544       1.2  christos         }
    545       1.1     elric 
    546       1.1     elric 	memcpy(*pp, p, size);
    547       1.1     elric 	free(p);
    548       1.1     elric 
    549       1.1     elric 	*pp += size;
    550       1.1     elric     }
    551       1.1     elric 
    552       1.1     elric     return size;
    553       1.1     elric }
    554