1 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
2 | * All rights reserved. |
3 | * |
4 | * This package is an SSL implementation written |
5 | * by Eric Young (eay@cryptsoft.com). |
6 | * The implementation was written so as to conform with Netscapes SSL. |
7 | * |
8 | * This library is free for commercial and non-commercial use as long as |
9 | * the following conditions are aheared to. The following conditions |
10 | * apply to all code found in this distribution, be it the RC4, RSA, |
11 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
12 | * included with this distribution is covered by the same copyright terms |
13 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
14 | * |
15 | * Copyright remains Eric Young's, and as such any Copyright notices in |
16 | * the code are not to be removed. |
17 | * If this package is used in a product, Eric Young should be given attribution |
18 | * as the author of the parts of the library used. |
19 | * This can be in the form of a textual message at program startup or |
20 | * in documentation (online or textual) provided with the package. |
21 | * |
22 | * Redistribution and use in source and binary forms, with or without |
23 | * modification, are permitted provided that the following conditions |
24 | * are met: |
25 | * 1. Redistributions of source code must retain the copyright |
26 | * notice, this list of conditions and the following disclaimer. |
27 | * 2. Redistributions in binary form must reproduce the above copyright |
28 | * notice, this list of conditions and the following disclaimer in the |
29 | * documentation and/or other materials provided with the distribution. |
30 | * 3. All advertising materials mentioning features or use of this software |
31 | * must display the following acknowledgement: |
32 | * "This product includes cryptographic software written by |
33 | * Eric Young (eay@cryptsoft.com)" |
34 | * The word 'cryptographic' can be left out if the rouines from the library |
35 | * being used are not cryptographic related :-). |
36 | * 4. If you include any Windows specific code (or a derivative thereof) from |
37 | * the apps directory (application code) you must include an acknowledgement: |
38 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
39 | * |
40 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
41 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
42 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
43 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
44 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
45 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
46 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
48 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
49 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
50 | * SUCH DAMAGE. |
51 | * |
52 | * The licence and distribution terms for any publically available version or |
53 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
54 | * copied and put under another distribution licence |
55 | * [including the GNU Public Licence.] */ |
56 | |
57 | #ifndef OPENSSL_HEADER_DH_H |
58 | #define |
59 | |
60 | #include <openssl/base.h> |
61 | |
62 | #include <openssl/ex_data.h> |
63 | #include <openssl/thread.h> |
64 | |
65 | #if defined(__cplusplus) |
66 | extern "C" { |
67 | #endif |
68 | |
69 | |
70 | // DH contains functions for performing Diffie-Hellman key agreement in |
71 | // multiplicative groups. |
72 | |
73 | |
74 | // Allocation and destruction. |
75 | |
76 | // DH_new returns a new, empty DH object or NULL on error. |
77 | OPENSSL_EXPORT DH *DH_new(void); |
78 | |
79 | // DH_free decrements the reference count of |dh| and frees it if the reference |
80 | // count drops to zero. |
81 | OPENSSL_EXPORT void DH_free(DH *dh); |
82 | |
83 | // DH_up_ref increments the reference count of |dh| and returns one. |
84 | OPENSSL_EXPORT int DH_up_ref(DH *dh); |
85 | |
86 | |
87 | // Properties. |
88 | |
89 | // DH_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dh|'s |
90 | // public and private key, respectively. If |dh| is a public key, the private |
91 | // key will be set to NULL. |
92 | OPENSSL_EXPORT void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, |
93 | const BIGNUM **out_priv_key); |
94 | |
95 | // DH_set0_key sets |dh|'s public and private key to the specified values. If |
96 | // NULL, the field is left unchanged. On success, it takes ownership of each |
97 | // argument and returns one. Otherwise, it returns zero. |
98 | OPENSSL_EXPORT int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); |
99 | |
100 | // DH_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dh|'s p, |
101 | // q, and g parameters, respectively. |
102 | OPENSSL_EXPORT void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, |
103 | const BIGNUM **out_q, const BIGNUM **out_g); |
104 | |
105 | // DH_set0_pqg sets |dh|'s p, q, and g parameters to the specified values. If |
106 | // NULL, the field is left unchanged. On success, it takes ownership of each |
107 | // argument and returns one. Otherwise, it returns zero. |q| may be NULL, but |
108 | // |p| and |g| must either be specified or already configured on |dh|. |
109 | OPENSSL_EXPORT int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); |
110 | |
111 | |
112 | // Standard parameters. |
113 | |
114 | // BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC |
115 | // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated |
116 | // and returned. It returns NULL on allocation failure. |
117 | OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); |
118 | |
119 | |
120 | // Parameter generation. |
121 | |
122 | #define DH_GENERATOR_2 2 |
123 | #define DH_GENERATOR_5 5 |
124 | |
125 | // DH_generate_parameters_ex generates a suitable Diffie-Hellman group with a |
126 | // prime that is |prime_bits| long and stores it in |dh|. The generator of the |
127 | // group will be |generator|, which should be |DH_GENERATOR_2| unless there's a |
128 | // good reason to use a different value. The |cb| argument contains a callback |
129 | // function that will be called during the generation. See the documentation in |
130 | // |bn.h| about this. In addition to the callback invocations from |BN|, |cb| |
131 | // will also be called with |event| equal to three when the generation is |
132 | // complete. |
133 | OPENSSL_EXPORT int DH_generate_parameters_ex(DH *dh, int prime_bits, |
134 | int generator, BN_GENCB *cb); |
135 | |
136 | |
137 | // Diffie-Hellman operations. |
138 | |
139 | // DH_generate_key generates a new, random, private key and stores it in |
140 | // |dh|. It returns one on success and zero on error. |
141 | OPENSSL_EXPORT int DH_generate_key(DH *dh); |
142 | |
143 | // DH_compute_key calculates the shared key between |dh| and |peers_key| and |
144 | // writes it as a big-endian integer into |out|, which must have |DH_size| |
145 | // bytes of space. It returns the number of bytes written, or a negative number |
146 | // on error. |
147 | OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, |
148 | DH *dh); |
149 | |
150 | |
151 | // Utility functions. |
152 | |
153 | // DH_size returns the number of bytes in the DH group's prime. |
154 | OPENSSL_EXPORT int DH_size(const DH *dh); |
155 | |
156 | // DH_num_bits returns the minimum number of bits needed to represent the |
157 | // absolute value of the DH group's prime. |
158 | OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh); |
159 | |
160 | #define DH_CHECK_P_NOT_PRIME 0x01 |
161 | #define DH_CHECK_P_NOT_SAFE_PRIME 0x02 |
162 | #define DH_CHECK_UNABLE_TO_CHECK_GENERATOR 0x04 |
163 | #define DH_CHECK_NOT_SUITABLE_GENERATOR 0x08 |
164 | #define DH_CHECK_Q_NOT_PRIME 0x10 |
165 | #define DH_CHECK_INVALID_Q_VALUE 0x20 |
166 | #define DH_CHECK_INVALID_J_VALUE 0x40 |
167 | |
168 | // These are compatibility defines. |
169 | #define DH_NOT_SUITABLE_GENERATOR DH_CHECK_NOT_SUITABLE_GENERATOR |
170 | #define DH_UNABLE_TO_CHECK_GENERATOR DH_CHECK_UNABLE_TO_CHECK_GENERATOR |
171 | |
172 | // DH_check checks the suitability of |dh| as a Diffie-Hellman group. and sets |
173 | // |DH_CHECK_*| flags in |*out_flags| if it finds any errors. It returns one if |
174 | // |*out_flags| was successfully set and zero on error. |
175 | // |
176 | // Note: these checks may be quite computationally expensive. |
177 | OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags); |
178 | |
179 | #define DH_CHECK_PUBKEY_TOO_SMALL 0x1 |
180 | #define DH_CHECK_PUBKEY_TOO_LARGE 0x2 |
181 | #define DH_CHECK_PUBKEY_INVALID 0x4 |
182 | |
183 | // DH_check_pub_key checks the suitability of |pub_key| as a public key for the |
184 | // DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it |
185 | // finds any errors. It returns one if |*out_flags| was successfully set and |
186 | // zero on error. |
187 | OPENSSL_EXPORT int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, |
188 | int *out_flags); |
189 | |
190 | // DHparams_dup allocates a fresh |DH| and copies the parameters from |dh| into |
191 | // it. It returns the new |DH| or NULL on error. |
192 | OPENSSL_EXPORT DH *DHparams_dup(const DH *dh); |
193 | |
194 | |
195 | // ASN.1 functions. |
196 | |
197 | // DH_parse_parameters decodes a DER-encoded DHParameter structure (PKCS #3) |
198 | // from |cbs| and advances |cbs|. It returns a newly-allocated |DH| or NULL on |
199 | // error. |
200 | OPENSSL_EXPORT DH *DH_parse_parameters(CBS *cbs); |
201 | |
202 | // DH_marshal_parameters marshals |dh| as a DER-encoded DHParameter structure |
203 | // (PKCS #3) and appends the result to |cbb|. It returns one on success and zero |
204 | // on error. |
205 | OPENSSL_EXPORT int DH_marshal_parameters(CBB *cbb, const DH *dh); |
206 | |
207 | |
208 | // ex_data functions. |
209 | // |
210 | // See |ex_data.h| for details. |
211 | |
212 | OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp, |
213 | CRYPTO_EX_unused *unused, |
214 | CRYPTO_EX_dup *dup_unused, |
215 | CRYPTO_EX_free *free_func); |
216 | OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg); |
217 | OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx); |
218 | |
219 | |
220 | // Deprecated functions. |
221 | |
222 | // DH_generate_parameters behaves like |DH_generate_parameters_ex|, which is |
223 | // what you should use instead. It returns NULL on error, or a newly-allocated |
224 | // |DH| on success. This function is provided for compatibility only. |
225 | OPENSSL_EXPORT DH *DH_generate_parameters(int prime_len, int generator, |
226 | void (*callback)(int, int, void *), |
227 | void *cb_arg); |
228 | |
229 | // d2i_DHparams parses an ASN.1, DER encoded Diffie-Hellman parameters structure |
230 | // from |len| bytes at |*inp|. If |ret| is not NULL then, on exit, a pointer to |
231 | // the result is in |*ret|. Note that, even if |*ret| is already non-NULL on |
232 | // entry, it will not be written to. Rather, a fresh |DH| is allocated and the |
233 | // previous one is freed. |
234 | // |
235 | // On successful exit, |*inp| is advanced past the DER structure. It |
236 | // returns the result or NULL on error. |
237 | // |
238 | // Use |DH_parse_parameters| instead. |
239 | OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len); |
240 | |
241 | // i2d_DHparams marshals |in| to an ASN.1, DER structure. If |outp| is not NULL |
242 | // then the result is written to |*outp| and |*outp| is advanced just past the |
243 | // output. It returns the number of bytes in the result, whether written or |
244 | // not, or a negative value on error. |
245 | // |
246 | // Use |DH_marshal_parameters| instead. |
247 | OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp); |
248 | |
249 | |
250 | struct dh_st { |
251 | BIGNUM *p; |
252 | BIGNUM *g; |
253 | BIGNUM *pub_key; // g^x mod p |
254 | BIGNUM *priv_key; // x |
255 | |
256 | // priv_length contains the length, in bits, of the private value. If zero, |
257 | // the private value will be the same length as |p|. |
258 | unsigned priv_length; |
259 | |
260 | CRYPTO_MUTEX method_mont_p_lock; |
261 | BN_MONT_CTX *method_mont_p; |
262 | |
263 | // Place holders if we want to do X9.42 DH |
264 | BIGNUM *q; |
265 | BIGNUM *j; |
266 | unsigned char *seed; |
267 | int seedlen; |
268 | BIGNUM *counter; |
269 | |
270 | int flags; |
271 | CRYPTO_refcount_t references; |
272 | CRYPTO_EX_DATA ex_data; |
273 | }; |
274 | |
275 | |
276 | #if defined(__cplusplus) |
277 | } // extern C |
278 | |
279 | extern "C++" { |
280 | |
281 | BSSL_NAMESPACE_BEGIN |
282 | |
283 | BORINGSSL_MAKE_DELETER(DH, DH_free) |
284 | BORINGSSL_MAKE_UP_REF(DH, DH_up_ref) |
285 | |
286 | BSSL_NAMESPACE_END |
287 | |
288 | } // extern C++ |
289 | |
290 | #endif |
291 | |
292 | #define DH_R_BAD_GENERATOR 100 |
293 | #define DH_R_INVALID_PUBKEY 101 |
294 | #define DH_R_MODULUS_TOO_LARGE 102 |
295 | #define DH_R_NO_PRIVATE_VALUE 103 |
296 | #define DH_R_DECODE_ERROR 104 |
297 | #define DH_R_ENCODE_ERROR 105 |
298 | |
299 | #endif // OPENSSL_HEADER_DH_H |
300 | |