1 /* ====================================================================
2  * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the OpenSSL Project
19  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20  *
21  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    licensing@OpenSSL.org.
25  *
26  * 5. Products derived from this software may not be called "OpenSSL"
27  *    nor may "OpenSSL" appear in their names without prior written
28  *    permission of the OpenSSL Project.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the OpenSSL Project
33  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This product includes cryptographic software written by Eric Young
50  * (eay@cryptsoft.com).  This product includes software written by Tim
51  * Hudson (tjh@cryptsoft.com). */
52 
53 #include <openssl/dh.h>
54 
55 #include <openssl/bn.h>
56 
57 #include "internal.h"
58 
59 
60 #if BN_BITS2 == 32
61 #define TOBN(lo, hi) lo, hi
62 #elif BN_BITS2 == 64
63 #define TOBN(lo, hi) ((BN_ULONG)hi << 32 | lo)
64 #else
65 #error "unsupported BN_BITS2"
66 #endif
67 
68 static const BN_ULONG dh1024_160_p[] = {
69     TOBN(0x2E4A4371, 0xDF1FB2BC), TOBN(0x6D4DA708, 0xE68CFDA7),
70     TOBN(0x365C1A65, 0x45BF37DF), TOBN(0x0DC8B4BD, 0xA151AF5F),
71     TOBN(0xF55BCCC0, 0xFAA31A4F), TOBN(0xE5644738, 0x4EFFD6FA),
72     TOBN(0x219A7372, 0x98488E9C), TOBN(0x90C4BD70, 0xACCBDD7D),
73     TOBN(0xD49B83BF, 0x24975C3C), TOBN(0xA9061123, 0x13ECB4AE),
74     TOBN(0x2EE652C0, 0x9838EF1E), TOBN(0x75A23D18, 0x6073E286),
75     TOBN(0x52D23B61, 0x9A6A9DCA), TOBN(0xFB06A3C6, 0x52C99FBC),
76     TOBN(0xAE5D54EC, 0xDE92DE5E), TOBN(0xA080E01D, 0xB10B8F96),
77 };
78 static const BN_ULONG dh1024_160_g[] = {
79     TOBN(0x22B3B2E5, 0x855E6EEB), TOBN(0xF97C2A24, 0x858F4DCE),
80     TOBN(0x18D08BC8, 0x2D779D59), TOBN(0x8E73AFA3, 0xD662A4D1),
81     TOBN(0x69B6A28A, 0x1DBF0A01), TOBN(0x7A091F53, 0xA6A24C08),
82     TOBN(0x63F80A76, 0x909D0D22), TOBN(0xB9A92EE1, 0xD7FBD7D3),
83     TOBN(0x9E2749F4, 0x5E91547F), TOBN(0xB01B886A, 0x160217B4),
84     TOBN(0x5504F213, 0x777E690F), TOBN(0x5C41564B, 0x266FEA1E),
85     TOBN(0x14266D31, 0xD6406CFF), TOBN(0x58AC507F, 0xF8104DD2),
86     TOBN(0xEFB99905, 0x6765A442), TOBN(0xC3FD3412, 0xA4D1CBD5),
87 };
88 static const BN_ULONG dh1024_160_q[] = {
89     TOBN(0x49462353, 0x64B7CB9D), TOBN(0x8ABA4E7D, 0x81A8DF27), 0xF518AA87,
90 };
91 
92 static const BN_ULONG dh2048_224_p[] = {
93     TOBN(0x0C10E64F, 0x0AC4DFFE), TOBN(0x4E71B81C, 0xCF9DE538),
94     TOBN(0xFFA31F71, 0x7EF363E2), TOBN(0x6B8E75B9, 0xE3FB73C1),
95     TOBN(0x4BA80A29, 0xC9B53DCF), TOBN(0x16E79763, 0x23F10B0E),
96     TOBN(0x13042E9B, 0xC52172E4), TOBN(0xC928B2B9, 0xBE60E69C),
97     TOBN(0xB9E587E8, 0x80CD86A1), TOBN(0x98C641A4, 0x315D75E1),
98     TOBN(0x44328387, 0xCDF93ACC), TOBN(0xDC0A486D, 0x15987D9A),
99     TOBN(0x1FD5A074, 0x7310F712), TOBN(0xDE31EFDC, 0x278273C7),
100     TOBN(0x415D9330, 0x1602E714), TOBN(0xBC8985DB, 0x81286130),
101     TOBN(0x70918836, 0xB3BF8A31), TOBN(0xB9C49708, 0x6A00E0A0),
102     TOBN(0x8BBC27BE, 0xC6BA0B2C), TOBN(0xED34DBF6, 0xC9F98D11),
103     TOBN(0xB6C12207, 0x7AD5B7D0), TOBN(0x55B7394B, 0xD91E8FEF),
104     TOBN(0xEFDA4DF8, 0x9037C9ED), TOBN(0xAD6AC212, 0x6D3F8152),
105     TOBN(0x1274A0A6, 0x1DE6B85A), TOBN(0x309C180E, 0xEB3D688A),
106     TOBN(0x7BA1DF15, 0xAF9A3C40), TOBN(0xF95A56DB, 0xE6FA141D),
107     TOBN(0xB61D0A75, 0xB54B1597), TOBN(0x683B9FD1, 0xA20D64E5),
108     TOBN(0x9559C51F, 0xD660FAA7), TOBN(0x9123A9D0, 0xAD107E1E),
109 };
110 
111 static const BN_ULONG dh2048_224_g[] = {
112     TOBN(0x191F2BFA, 0x84B890D3), TOBN(0x2A7065B3, 0x81BC087F),
113     TOBN(0xF6EC0179, 0x19C418E1), TOBN(0x71CFFF4C, 0x7B5A0F1C),
114     TOBN(0x9B6AA4BD, 0xEDFE72FE), TOBN(0x94B30269, 0x81E1BCFE),
115     TOBN(0x8D6C0191, 0x566AFBB4), TOBN(0x409D13CD, 0xB539CCE3),
116     TOBN(0x5F2FF381, 0x6AA21E7F), TOBN(0x770589EF, 0xD9E263E4),
117     TOBN(0xD19963DD, 0x10E183ED), TOBN(0x150B8EEB, 0xB70A8137),
118     TOBN(0x28C8F8AC, 0x051AE3D4), TOBN(0x0C1AB15B, 0xBB77A86F),
119     TOBN(0x16A330EF, 0x6E3025E3), TOBN(0xD6F83456, 0x19529A45),
120     TOBN(0x118E98D1, 0xF180EB34), TOBN(0x50717CBE, 0xB5F6C6B2),
121     TOBN(0xDA7460CD, 0x09939D54), TOBN(0x22EA1ED4, 0xE2471504),
122     TOBN(0x521BC98A, 0xB8A762D0), TOBN(0x5AC1348B, 0xF4D02727),
123     TOBN(0x1999024A, 0xC1766910), TOBN(0xA8D66AD7, 0xBE5E9001),
124     TOBN(0x620A8652, 0xC57DB17C), TOBN(0x00C29F52, 0xAB739D77),
125     TOBN(0xA70C4AFA, 0xDD921F01), TOBN(0x10B9A6F0, 0xA6824A4E),
126     TOBN(0xCFE4FFE3, 0x74866A08), TOBN(0x89998CAF, 0x6CDEBE7B),
127     TOBN(0x8FFDAC50, 0x9DF30B5C), TOBN(0x4F2D9AE3, 0xAC4032EF),
128 };
129 
130 static const BN_ULONG dh2048_224_q[] = {
131     TOBN(0xB36371EB, 0xBF389A99), TOBN(0x4738CEBC, 0x1F80535A),
132     TOBN(0x99717710, 0xC58D93FE), 0x801C0D34,
133 };
134 
135 static const BN_ULONG dh2048_256_p[] = {
136     TOBN(0x1E1A1597, 0xDB094AE9), TOBN(0xD7EF09CA, 0x693877FA),
137     TOBN(0x6E11715F, 0x6116D227), TOBN(0xC198AF12, 0xA4B54330),
138     TOBN(0xD7014103, 0x75F26375), TOBN(0x54E710C3, 0xC3A3960A),
139     TOBN(0xBD0BE621, 0xDED4010A), TOBN(0x89962856, 0xC0B857F6),
140     TOBN(0x71506026, 0xB3CA3F79), TOBN(0xE6B486F6, 0x1CCACB83),
141     TOBN(0x14056425, 0x67E144E5), TOBN(0xA41825D9, 0xF6A167B5),
142     TOBN(0x96524D8E, 0x3AD83477), TOBN(0x51BFA4AB, 0xF13C6D9A),
143     TOBN(0x35488A0E, 0x2D525267), TOBN(0xCAA6B790, 0xB63ACAE1),
144     TOBN(0x81B23F76, 0x4FDB70C5), TOBN(0x12307F5C, 0xBC39A0BF),
145     TOBN(0xB1E59BB8, 0xB941F54E), TOBN(0xD45F9088, 0x6C5BFC11),
146     TOBN(0x4275BF7B, 0x22E0B1EF), TOBN(0x5B4758C0, 0x91F9E672),
147     TOBN(0x6BCF67ED, 0x5A8A9D30), TOBN(0x97517ABD, 0x209E0C64),
148     TOBN(0x830E9A7C, 0x3BF4296D), TOBN(0x34096FAA, 0x16C3D911),
149     TOBN(0x61B2AA30, 0xFAF7DF45), TOBN(0xD61957D4, 0xE00DF8F1),
150     TOBN(0x435E3B00, 0x5D2CEED4), TOBN(0x660DD0F2, 0x8CEEF608),
151     TOBN(0x65195999, 0xFFBBD19C), TOBN(0xB4B6663C, 0x87A8E61D),
152 };
153 static const BN_ULONG dh2048_256_g[] = {
154     TOBN(0x6CC41659, 0x664B4C0F), TOBN(0xEF98C582, 0x5E2327CF),
155     TOBN(0xD4795451, 0xD647D148), TOBN(0x90F00EF8, 0x2F630784),
156     TOBN(0x1DB246C3, 0x184B523D), TOBN(0xCDC67EB6, 0xC7891428),
157     TOBN(0x0DF92B52, 0x7FD02837), TOBN(0x64E0EC37, 0xB3353BBB),
158     TOBN(0x57CD0915, 0xECD06E15), TOBN(0xDF016199, 0xB7D2BBD2),
159     TOBN(0x052588B9, 0xC8484B1E), TOBN(0x13D3FE14, 0xDB2A3B73),
160     TOBN(0xD182EA0A, 0xD052B985), TOBN(0xE83B9C80, 0xA4BD1BFF),
161     TOBN(0xFB3F2E55, 0xDFC967C1), TOBN(0x767164E1, 0xB5045AF2),
162     TOBN(0x6F2F9193, 0x1D14348F), TOBN(0x428EBC83, 0x64E67982),
163     TOBN(0x82D6ED38, 0x8AC376D2), TOBN(0xAAB8A862, 0x777DE62A),
164     TOBN(0xE9EC144B, 0xDDF463E5), TOBN(0xC77A57F2, 0x0196F931),
165     TOBN(0x41000A65, 0xA55AE313), TOBN(0xC28CBB18, 0x901228F8),
166     TOBN(0x7E8C6F62, 0xBC3773BF), TOBN(0x0C6B47B1, 0xBE3A6C1B),
167     TOBN(0xAC0BB555, 0xFF4FED4A), TOBN(0x77BE463F, 0x10DBC150),
168     TOBN(0x1A0BA125, 0x07F4793A), TOBN(0x21EF2054, 0x4CA7B18F),
169     TOBN(0x60EDBD48, 0x2E775066), TOBN(0x73134D0B, 0x3FB32C9B),
170 };
171 static const BN_ULONG dh2048_256_q[] = {
172     TOBN(0x64F5FBD3, 0xA308B0FE), TOBN(0x1EB3750B, 0x99B1A47D),
173     TOBN(0x40129DA2, 0xB4479976), TOBN(0xA709A097, 0x8CF83642),
174 };
175 
176 /* dh1024_safe_prime_1 is hard-coded in Apache httpd 2.2,
177  * modules/ssl/ssl_engine_dh.c. */
178 static const BN_ULONG dh1024_safe_prime_1[] = {
179     TOBN(0x24218EB3, 0xE7393E0F), TOBN(0xE2BD68B0, 0x7DE0F4D6),
180     TOBN(0x88AEAA74, 0x07DD62DB), TOBN(0x9DDD3305, 0x10EA9FCC),
181     TOBN(0x74087D15, 0xA7DBCA78), TOBN(0x78045B07, 0xDAE88600),
182     TOBN(0x1AAD3B72, 0x33168A46), TOBN(0x7BEDDCFD, 0xFF590137),
183     TOBN(0x7A635E81, 0xFE324A46), TOBN(0x420B2A29, 0x5AC179BA),
184     TOBN(0x177E16D5, 0x13B4B4D7), TOBN(0x639C72FB, 0x849F912E),
185     TOBN(0x98BCE951, 0xB88174CB), TOBN(0xA45F520B, 0x0C84D239),
186     TOBN(0x4AFD0AD5, 0x36D693D3), TOBN(0xCBBBDC19, 0xD67DE440),
187 };
188 
189 /* dh1024_safe_prime_2 is hard-coded in nginx,
190  * src/event/ngx_event_openssl.c. */
191 static const BN_ULONG dh1024_safe_prime_2[] = {
192     TOBN(0xCFE16B9B, 0x071DF045), TOBN(0x146757DA, 0x88D0F65D),
193     TOBN(0x58FAFD49, 0x4A63AB1E), TOBN(0xEF9EA027, 0x35D8CECE),
194     TOBN(0x70CC9A50, 0x25ECE662), TOBN(0x81DC2CA7, 0xF29BA5DF),
195     TOBN(0xF7D36CC8, 0x8F68B076), TOBN(0xA757E304, 0x60E91A92),
196     TOBN(0x9BE67780, 0x87A2BC04), TOBN(0xA5FDF1D2, 0xBEECA565),
197     TOBN(0x922614C5, 0x5CCBBAA8), TOBN(0xE710800C, 0x6C030276),
198     TOBN(0x0FB3504C, 0x08EED4EB), TOBN(0x68B42D4B, 0xD958A3F5),
199     TOBN(0x80E9CFDB, 0x7C43FCF5), TOBN(0xD8467490, 0xBBBC2DCA),
200 };
201 
202 /* dh1024_safe_prime_3 is offered as a parameter by several high-traffic sites,
203  * including mozilla.org, as of Jan 2015. */
204 static const BN_ULONG dh1024_safe_prime_3[] = {
205     TOBN(0x349E721B, 0x671746AE), TOBN(0xD75E93B2, 0x258A0655),
206     TOBN(0x25592EB6, 0xD425E6FB), TOBN(0xBF7CDD9A, 0x0C46AB04),
207     TOBN(0x28968680, 0x0AD0BC99), TOBN(0xD0B7EB49, 0xF53907FB),
208     TOBN(0xEBC85C1D, 0x202EABB3), TOBN(0x364D8C71, 0x3129C693),
209     TOBN(0x2D46F195, 0x53728351), TOBN(0x8C76CC85, 0xDF326DD6),
210     TOBN(0x9188E24E, 0xF898B3F9), TOBN(0x2855DFD2, 0x95EFB13C),
211     TOBN(0x7B2241FE, 0x1F5DAC48), TOBN(0x99A13D9F, 0x117B6BF7),
212     TOBN(0x3A3468C7, 0x0F97CDDA), TOBN(0x74A8297B, 0xC9BBF5F7)};
213 
214 /* dh1024_safe_prime_4 is hard-coded in Apache httpd 2.0,
215  * modules/ssl/ssl_engine_dh.c. */
216 static const BN_ULONG dh1024_safe_prime_4[] = {
217     TOBN(0x0DD5C86B, 0x5085E21F), TOBN(0xD823C650, 0x871538DF),
218     TOBN(0x262E56A8, 0x125136F7), TOBN(0x839EB5DB, 0x974E9EF1),
219     TOBN(0x1B13A63C, 0xEA9BAD99), TOBN(0x3D76E05E, 0x6044CF02),
220     TOBN(0x1BAC9B5C, 0x611EBBBE), TOBN(0x4E5327DF, 0x3E371D79),
221     TOBN(0x061CBC05, 0x000E6EDD), TOBN(0x20129B48, 0x2F971F3C),
222     TOBN(0x3048D5A2, 0xA6EF09C4), TOBN(0xCBD523A6, 0xFA15A259),
223     TOBN(0x4A79A770, 0x2A206490), TOBN(0x51BB055E, 0x91B78182),
224     TOBN(0xBDD4798E, 0x7CF180C3), TOBN(0x495BE32C, 0xE6969D3D)};
225 
226 static const BN_ULONG bn_two_data[] = {2};
227 
228 #define STATIC_BIGNUM(x)                                     \
229   {                                                          \
230     (BN_ULONG *) x, sizeof(x) / sizeof(BN_ULONG),            \
231         sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
232   }
233 
234 struct standard_parameters {
235   BIGNUM p, q, g;
236 };
237 
238 static const struct standard_parameters dh1024_160 = {
239   STATIC_BIGNUM(dh1024_160_p),
240   STATIC_BIGNUM(dh1024_160_q),
241   STATIC_BIGNUM(dh1024_160_g),
242 };
243 
244 static const struct standard_parameters dh2048_224 = {
245   STATIC_BIGNUM(dh2048_224_p),
246   STATIC_BIGNUM(dh2048_224_q),
247   STATIC_BIGNUM(dh2048_224_g),
248 };
249 
250 static const struct standard_parameters dh2048_256 = {
251   STATIC_BIGNUM(dh2048_256_p),
252   STATIC_BIGNUM(dh2048_256_q),
253   STATIC_BIGNUM(dh2048_256_g),
254 };
255 
256 static const BIGNUM dh1024_safe_prime[] = {
257   STATIC_BIGNUM(dh1024_safe_prime_1),
258   STATIC_BIGNUM(dh1024_safe_prime_2),
259   STATIC_BIGNUM(dh1024_safe_prime_3),
260   STATIC_BIGNUM(dh1024_safe_prime_4)
261 };
262 
263 BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
264 
get_standard_parameters(const struct standard_parameters * params,const ENGINE * engine)265 static DH *get_standard_parameters(const struct standard_parameters *params,
266                                    const ENGINE *engine) {
267   DH *dh;
268 
269   dh = DH_new_method(engine);
270   if (!dh) {
271     return NULL;
272   }
273 
274   dh->p = BN_dup(&params->p);
275   dh->q = BN_dup(&params->q);
276   dh->g = BN_dup(&params->g);
277   if (!dh->p || !dh->q || !dh->g) {
278     DH_free(dh);
279     return NULL;
280   }
281 
282   return dh;
283 }
284 
DH_get_1024_160(const ENGINE * engine)285 DH *DH_get_1024_160(const ENGINE *engine) {
286   return get_standard_parameters(&dh1024_160, engine);
287 }
288 
DH_get_2048_224(const ENGINE * engine)289 DH *DH_get_2048_224(const ENGINE *engine) {
290   return get_standard_parameters(&dh2048_224, engine);
291 }
292 
DH_get_2048_256(const ENGINE * engine)293 DH *DH_get_2048_256(const ENGINE *engine) {
294   return get_standard_parameters(&dh2048_256, engine);
295 }
296 
DH_check_standard_parameters(DH * dh)297 void DH_check_standard_parameters(DH *dh) {
298   int i;
299 
300   if (dh->p == NULL ||
301       dh->g == NULL ||
302       BN_num_bytes(dh->p) != (1024 / 8) ||
303       BN_cmp(dh->g, &bn_two) != 0) {
304     return;
305   }
306 
307   for (i = 0; i < sizeof(dh1024_safe_prime) / sizeof(dh1024_safe_prime[0]);
308        i++) {
309     if (BN_cmp(dh->p, &dh1024_safe_prime[i]) == 0) {
310       /* The well-known DH groups are known to have safe primes. In this case
311        * we can safely reduce the size of the private key. */
312       dh->priv_length = 161;
313       break;
314     }
315   }
316 }
317