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