OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
dh_pmeth.c
Go to the documentation of this file.
1 /* Written by Dr Stephen N Henson ([email protected]) 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
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  * ([email protected]). This product includes software written by Tim
54  * Hudson ([email protected]).
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  {
123  if (p1 < 256)
124  return -2;
125  dctx->prime_len = p1;
126  return 1;
127 
129  dctx->generator = p1;
130  return 1;
131 
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);
151  }
152  if (!strcmp(type, "dh_paramgen_generator"))
153  {
154  int len;
155  len = atoi(value);
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  {
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  {
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 
221  {
222  EVP_PKEY_DH,
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  };