Home | History | Annotate | Line # | Download | only in hcrypto
      1  1.1     elric /*	$NetBSD: dh.c,v 1.3 2023/06/19 21:41:43 christos 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.3  christos 	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