Home | History | Annotate | Download | only in dh
      1 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL
      2  * project 2006.
      3  */
      4 /* ====================================================================
      5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in
     16  *    the documentation and/or other materials provided with the
     17  *    distribution.
     18  *
     19  * 3. All advertising materials mentioning features or use of this
     20  *    software must display the following acknowledgment:
     21  *    "This product includes software developed by the OpenSSL Project
     22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     23  *
     24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     25  *    endorse or promote products derived from this software without
     26  *    prior written permission. For written permission, please contact
     27  *    licensing (at) OpenSSL.org.
     28  *
     29  * 5. Products derived from this software may not be called "OpenSSL"
     30  *    nor may "OpenSSL" appear in their names without prior written
     31  *    permission of the OpenSSL Project.
     32  *
     33  * 6. Redistributions of any form whatsoever must retain the following
     34  *    acknowledgment:
     35  *    "This product includes software developed by the OpenSSL Project
     36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     37  *
     38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     49  * OF THE POSSIBILITY OF SUCH DAMAGE.
     50  * ====================================================================
     51  *
     52  * This product includes cryptographic software written by Eric Young
     53  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     54  * Hudson (tjh (at) cryptsoft.com).
     55  *
     56  */
     57 
     58 #include <stdio.h>
     59 #include "cryptlib.h"
     60 #include <openssl/asn1t.h>
     61 #include <openssl/x509.h>
     62 #include <openssl/evp.h>
     63 #include <openssl/dh.h>
     64 #include <openssl/bn.h>
     65 #include "evp_locl.h"
     66 
     67 /* DH pkey context structure */
     68 
     69 typedef struct
     70 	{
     71 	/* Parameter gen parameters */
     72 	int prime_len;
     73 	int generator;
     74 	int use_dsa;
     75 	/* Keygen callback info */
     76 	int gentmp[2];
     77 	/* message digest */
     78 	} DH_PKEY_CTX;
     79 
     80 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
     81 	{
     82 	DH_PKEY_CTX *dctx;
     83 	dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
     84 	if (!dctx)
     85 		return 0;
     86 	dctx->prime_len = 1024;
     87 	dctx->generator = 2;
     88 	dctx->use_dsa = 0;
     89 
     90 	ctx->data = dctx;
     91 	ctx->keygen_info = dctx->gentmp;
     92 	ctx->keygen_info_count = 2;
     93 
     94 	return 1;
     95 	}
     96 
     97 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     98 	{
     99 	DH_PKEY_CTX *dctx, *sctx;
    100 	if (!pkey_dh_init(dst))
    101 		return 0;
    102        	sctx = src->data;
    103 	dctx = dst->data;
    104 	dctx->prime_len = sctx->prime_len;
    105 	dctx->generator = sctx->generator;
    106 	dctx->use_dsa = sctx->use_dsa;
    107 	return 1;
    108 	}
    109 
    110 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
    111 	{
    112 	DH_PKEY_CTX *dctx = ctx->data;
    113 	if (dctx)
    114 		OPENSSL_free(dctx);
    115 	}
    116 
    117 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
    118 	{
    119 	DH_PKEY_CTX *dctx = ctx->data;
    120 	switch (type)
    121 		{
    122 		case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
    123 		if (p1 < 256)
    124 			return -2;
    125 		dctx->prime_len = p1;
    126 		return 1;
    127 
    128 		case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
    129 		dctx->generator = p1;
    130 		return 1;
    131 
    132 		case EVP_PKEY_CTRL_PEER_KEY:
    133 		/* Default behaviour is OK */
    134 		return 1;
    135 
    136 		default:
    137 		return -2;
    138 
    139 		}
    140 	}
    141 
    142 
    143 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
    144 			const char *type, const char *value)
    145 	{
    146 	if (!strcmp(type, "dh_paramgen_prime_len"))
    147 		{
    148 		int len;
    149 		len = atoi(value);
    150 		return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
    151 		}
    152 	if (!strcmp(type, "dh_paramgen_generator"))
    153 		{
    154 		int len;
    155 		len = atoi(value);
    156 		return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
    157 		}
    158 	return -2;
    159 	}
    160 
    161 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
    162 	{
    163 	DH *dh = NULL;
    164 	DH_PKEY_CTX *dctx = ctx->data;
    165 	BN_GENCB *pcb, cb;
    166 	int ret;
    167 	if (ctx->pkey_gencb)
    168 		{
    169 		pcb = &cb;
    170 		evp_pkey_set_cb_translate(pcb, ctx);
    171 		}
    172 	else
    173 		pcb = NULL;
    174 	dh = DH_new();
    175 	if (!dh)
    176 		return 0;
    177 	ret = DH_generate_parameters_ex(dh,
    178 					dctx->prime_len, dctx->generator, pcb);
    179 	if (ret)
    180 		EVP_PKEY_assign_DH(pkey, dh);
    181 	else
    182 		DH_free(dh);
    183 	return ret;
    184 	}
    185 
    186 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
    187 	{
    188 	DH *dh = NULL;
    189 	if (ctx->pkey == NULL)
    190 		{
    191 		DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
    192 		return 0;
    193 		}
    194 	dh = DH_new();
    195 	if (!dh)
    196 		return 0;
    197 	EVP_PKEY_assign_DH(pkey, dh);
    198 	/* Note: if error return, pkey is freed by parent routine */
    199 	if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
    200 		return 0;
    201 	return DH_generate_key(pkey->pkey.dh);
    202 	}
    203 
    204 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
    205 	{
    206 	int ret;
    207 	if (!ctx->pkey || !ctx->peerkey)
    208 		{
    209 		DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
    210 		return 0;
    211 		}
    212 	ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
    213 							ctx->pkey->pkey.dh);
    214 	if (ret < 0)
    215 		return ret;
    216 	*keylen = ret;
    217 	return 1;
    218 	}
    219 
    220 const EVP_PKEY_METHOD dh_pkey_meth =
    221 	{
    222 	EVP_PKEY_DH,
    223 	EVP_PKEY_FLAG_AUTOARGLEN,
    224 	pkey_dh_init,
    225 	pkey_dh_copy,
    226 	pkey_dh_cleanup,
    227 
    228 	0,
    229 	pkey_dh_paramgen,
    230 
    231 	0,
    232 	pkey_dh_keygen,
    233 
    234 	0,
    235 	0,
    236 
    237 	0,
    238 	0,
    239 
    240 	0,0,
    241 
    242 	0,0,0,0,
    243 
    244 	0,0,
    245 
    246 	0,0,
    247 
    248 	0,
    249 	pkey_dh_derive,
    250 
    251 	pkey_dh_ctrl,
    252 	pkey_dh_ctrl_str
    253 
    254 	};
    255