blob: e98148dcddfcb4bbd65c1504ba653cb179e4315a [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Diffie-Hellman-Merkle key exchange
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000022 * The following sources were referenced in the design of this implementation
23 * of the Diffie-Hellman-Merkle algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000024 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000025 * [1] Handbook of Applied Cryptography - 1997, Chapter 12
26 * Menezes, van Oorschot and Vanstone
27 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 */
29
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020044#endif
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020048#endif
49
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020052#else
53#include <stdlib.h>
Manuel Pégourié-Gonnard981732b2015-02-17 15:46:45 +000054#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#define mbedtls_printf printf
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020056#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#define mbedtls_free free
Paul Bakker40ce79f2013-09-15 17:43:54 +020058#endif
59
Hanno Becker0e6dc842017-09-27 11:48:02 +010060/*
61 * Diffie-Hellman groups from RFC 5114
62 *
63 * \warning The origin of the primes in RFC 5114 is not documented and
64 * their use therefore constitutes a security risk!
65 *
66 * \deprecated The primes from RFC 5114 are superseded by the primes
67 * from RFC 3526 and RFC 7919 and should no longer be used.
68 * They will be removed in the next major version.
69 */
70
71const char * mbedtls_dhm_rfc5114_modp_2048_p =
72 "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1"
73 "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15"
74 "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212"
75 "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207"
76 "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708"
77 "B3BF8A317091883681286130BC8985DB1602E714415D9330"
78 "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D"
79 "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8"
80 "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763"
81 "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71"
82 "CF9DE5384E71B81C0AC4DFFE0C10E64F";
83const char * mbedtls_dhm_rfc5114_modp_2048_g =
84 "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"
85 "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"
86 "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"
87 "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"
88 "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"
89 "F180EB34118E98D119529A45D6F834566E3025E316A330EF"
90 "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"
91 "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"
92 "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"
93 "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"
94 "81BC087F2A7065B384B890D3191F2BFA";
95
96/*
97 * Diffie-Hellman groups from RFC 3526
98 */
99
100const char * mbedtls_dhm_rfc3526_modp_2048_p =
101 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
102 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
103 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
104 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
105 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
106 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
107 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
108 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
109 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
110 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
111 "15728E5A8AACAA68FFFFFFFFFFFFFFFF";
112const char * mbedtls_dhm_rfc3526_modp_2048_g = "02";
113
114const char * mbedtls_dhm_rfc3526_modp_3072_p =
115 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
116 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
117 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
118 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
119 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
120 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
121 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
122 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
123 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
124 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
125 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
126 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
127 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
128 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
129 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
130 "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
131const char * mbedtls_dhm_rfc3526_modp_3072_g = "02";
132
133const char * mbedtls_dhm_rfc3526_modp_4096_p =
134 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
135 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
136 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
137 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
138 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
139 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
140 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
141 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
142 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
143 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
144 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
145 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
146 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
147 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
148 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
149 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
150 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
151 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
152 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
153 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
154 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
155 "FFFFFFFFFFFFFFFF";
156const char * mbedtls_dhm_rfc3526_modp_4096_g = "02";
Hanno Beckerb2bad802017-09-27 11:49:31 +0100157
158/*
159 * Diffie-Hellman groups from RFC 7919
160 */
161
162const char * mbedtls_dhm_rfc7919_ffdhe2048_p =
163 "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
164 "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
165 "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
166 "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
167 "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
168 "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
169 "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
170 "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
171 "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
172 "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
173 "886B423861285C97FFFFFFFFFFFFFFFF";
174const char * mbedtls_dhm_rfc7919_ffdhe2048_g = "02";
175
176const char * mbedtls_dhm_rfc7919_ffdhe3072_p =
177 "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
178 "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
179 "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
180 "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
181 "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
182 "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
183 "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
184 "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
185 "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
186 "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
187 "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
188 "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
189 "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
190 "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
191 "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
192 "3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF";
193const char * mbedtls_dhm_rfc7919_ffdhe3072_g = "02";
194
195const char * mbedtls_dhm_rfc7919_ffdhe4096_p =
196 "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
197 "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
198 "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
199 "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
200 "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
201 "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
202 "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
203 "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
204 "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
205 "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
206 "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
207 "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
208 "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
209 "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
210 "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
211 "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB"
212 "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004"
213 "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832"
214 "A907600A918130C46DC778F971AD0038092999A333CB8B7A"
215 "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF"
216 "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6A"
217 "FFFFFFFFFFFFFFFF";
218const char * mbedtls_dhm_rfc7919_ffdhe4096_g = "02";
219
220const char * mbedtls_dhm_rfc7919_ffdhe6144_p =
221 "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
222 "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
223 "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
224 "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
225 "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
226 "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
227 "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
228 "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
229 "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
230 "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
231 "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
232 "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
233 "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
234 "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
235 "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
236 "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB"
237 "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004"
238 "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832"
239 "A907600A918130C46DC778F971AD0038092999A333CB8B7A"
240 "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF"
241 "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902"
242 "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6"
243 "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A"
244 "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477"
245 "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3"
246 "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4"
247 "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6"
248 "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C"
249 "D72B03746AE77F5E62292C311562A846505DC82DB854338A"
250 "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04"
251 "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1"
252 "A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF";
253const char * mbedtls_dhm_rfc7919_ffdhe6144_g = "02";
254
255const char * mbedtls_dhm_rfc7919_ffdhe8192_p =
256 "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1"
257 "D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF9"
258 "7D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD6561"
259 "2433F51F5F066ED0856365553DED1AF3B557135E7F57C935"
260 "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE735"
261 "30ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FB"
262 "B96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB19"
263 "0B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"
264 "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD73"
265 "3BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA"
266 "886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C0238"
267 "61B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91C"
268 "AEFE130985139270B4130C93BC437944F4FD4452E2D74DD3"
269 "64F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0D"
270 "ABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF"
271 "3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB"
272 "7930E9E4E58857B6AC7D5F42D69F6D187763CF1D55034004"
273 "87F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832"
274 "A907600A918130C46DC778F971AD0038092999A333CB8B7A"
275 "1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF"
276 "8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD902"
277 "0BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA6"
278 "3BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3A"
279 "CDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477"
280 "A52471F7A9A96910B855322EDB6340D8A00EF092350511E3"
281 "0ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4"
282 "763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6"
283 "B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538C"
284 "D72B03746AE77F5E62292C311562A846505DC82DB854338A"
285 "E49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B04"
286 "5B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1"
287 "A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C838"
288 "1E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E"
289 "0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665"
290 "CB2C0F1CC01BD70229388839D2AF05E454504AC78B758282"
291 "2846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022"
292 "BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C"
293 "51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9"
294 "D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA457"
295 "1EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30"
296 "FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D"
297 "97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88C"
298 "D68C8BB7C5C6424CFFFFFFFF"
299 "FFFFFFFF";
300const char * mbedtls_dhm_rfc7919_ffdhe8192_g = "02";
301
302
Paul Bakker34617722014-06-13 17:20:13 +0200303/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +0200305 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
306}
307
Paul Bakker5121ce52009-01-03 21:22:43 +0000308/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000313 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000314{
315 int ret, n;
316
317 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
320 n = ( (*p)[0] << 8 ) | (*p)[1];
321 (*p) += 2;
322
323 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
327 return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329 (*p) += n;
330
331 return( 0 );
332}
333
334/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000335 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +0000336 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000337 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +0000338 *
339 * For more information on the attack, see:
340 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
341 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +0000342 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000344{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345 mbedtls_mpi L, U;
346 int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +0200349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
351 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 &&
354 mbedtls_mpi_cmp_mpi( param, &U ) <= 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000355 {
Paul Bakker345a6fe2011-02-28 21:20:02 +0000356 ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000357 }
358
Paul Bakker3d8fb632014-04-17 12:42:41 +0200359cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000361 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000362}
363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200365{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200367}
368
Paul Bakkerc47840e2011-02-20 16:37:30 +0000369/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 * Parse the ServerKeyExchange parameters
371 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000374 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000375{
Paul Bakker13ed9ab2012-04-16 09:43:49 +0000376 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000377
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
379 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
380 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
381 return( ret );
382
Paul Bakker345a6fe2011-02-28 21:20:02 +0000383 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
384 return( ret );
385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 ctx->len = mbedtls_mpi_size( &ctx->P );
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
Paul Bakker5121ce52009-01-03 21:22:43 +0000388 return( 0 );
389}
390
391/*
392 * Setup and write the ServerKeyExchange parameters
393 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000395 unsigned char *output, size_t *olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000396 int (*f_rng)(void *, unsigned char *, size_t),
397 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000398{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000399 int ret, count = 0;
Paul Bakker23986e52011-04-24 08:57:21 +0000400 size_t n1, n2, n3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 unsigned char *p;
402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
404 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000405
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 /*
Paul Bakkerff7fe672010-07-18 09:45:05 +0000407 * Generate X as large as possible ( < P )
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000409 do
410 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200411 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
414 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000415
416 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000418 }
419 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Paul Bakkerff7fe672010-07-18 09:45:05 +0000421 /*
422 * Calculate GX = G^X mod P
423 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 &ctx->P , &ctx->RP ) );
426
Paul Bakker345a6fe2011-02-28 21:20:02 +0000427 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000428 return( ret );
429
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 /*
431 * export P, G, GX
432 */
433#define DHM_MPI_EXPORT(X,n) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 *p++ = (unsigned char)( n >> 8 ); \
436 *p++ = (unsigned char)( n ); p += n;
437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 n1 = mbedtls_mpi_size( &ctx->P );
439 n2 = mbedtls_mpi_size( &ctx->G );
440 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
442 p = output;
443 DHM_MPI_EXPORT( &ctx->P , n1 );
444 DHM_MPI_EXPORT( &ctx->G , n2 );
445 DHM_MPI_EXPORT( &ctx->GX, n3 );
446
447 *olen = p - output;
448
449 ctx->len = n1;
450
451cleanup:
452
453 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 return( 0 );
457}
458
459/*
460 * Import the peer's public value G^Y
461 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000463 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000464{
465 int ret;
466
467 if( ctx == NULL || ilen < 1 || ilen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
471 return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 return( 0 );
474}
475
476/*
477 * Create own private value X and export G^X
478 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000480 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000481 int (*f_rng)(void *, unsigned char *, size_t),
482 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000483{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000484 int ret, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 if( ctx == NULL || olen < 1 || olen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
490 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000491
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 /*
493 * generate X and calculate GX = G^X mod P
494 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000495 do
496 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200497 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
500 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000501
502 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000504 }
505 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000508 &ctx->P , &ctx->RP ) );
509
Paul Bakker345a6fe2011-02-28 21:20:02 +0000510 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
511 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000514
515cleanup:
516
517 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
520 return( 0 );
521}
522
523/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200524 * Use the blinding method and optimisation suggested in section 10 of:
525 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200526 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200527 * Berlin Heidelberg, 1996. p. 104-113.
528 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200530 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
531{
532 int ret, count;
533
534 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200535 * Don't use any blinding the first time a particular X is used,
536 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200537 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200539 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
541 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
542 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200543
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200544 return( 0 );
545 }
546
547 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200548 * Ok, we need blinding. Can we re-use existing values?
549 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200550 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200552 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
554 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
557 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200558
559 return( 0 );
560 }
561
562 /*
563 * We need to generate blinding values from scratch
564 */
565
566 /* Vi = random( 2, P-1 ) */
567 count = 0;
568 do
569 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200570 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
573 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200574
575 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200577 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200579
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200580 /* Vf = Vi^-X mod P */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
582 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200583
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200584cleanup:
585 return( ret );
586}
587
588/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 * Derive and export the shared secret (G^Y)^X mod P
590 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100592 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200593 int (*f_rng)(void *, unsigned char *, size_t),
594 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
596 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200598
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100599 if( ctx == NULL || output_size < ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Paul Bakker345a6fe2011-02-28 21:20:02 +0000602 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000603 return( ret );
604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200606
607 /* Blind peer's value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200608 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200609 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
611 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
612 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200613 }
614 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200616
617 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200619 &ctx->P, &ctx->RP ) );
620
621 /* Unblind secret value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200622 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200623 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
625 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200626 }
627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 *olen = mbedtls_mpi_size( &ctx->K );
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
632cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
638 return( 0 );
639}
640
641/*
642 * Free the components of a DHM key
643 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000645{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi );
647 mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
648 mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G );
649 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651 mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000652}
653
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200655/*
656 * Parse DHM parameters
657 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200659 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200660{
661 int ret;
662 size_t len;
663 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664#if defined(MBEDTLS_PEM_PARSE_C)
665 mbedtls_pem_context pem;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200666
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200668
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200669 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200670 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200671 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
672 else
673 ret = mbedtls_pem_read_buffer( &pem,
674 "-----BEGIN DH PARAMETERS-----",
675 "-----END DH PARAMETERS-----",
676 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200677
678 if( ret == 0 )
679 {
680 /*
681 * Was PEM encoded
682 */
683 dhminlen = pem.buflen;
684 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200686 goto exit;
687
688 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
689#else
690 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200692 end = p + dhminlen;
693
694 /*
695 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400696 * prime INTEGER, -- P
697 * generator INTEGER, -- g
698 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200699 * }
700 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
702 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200703 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200705 goto exit;
706 }
707
708 end = p + len;
709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
711 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200712 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200714 goto exit;
715 }
716
717 if( p != end )
718 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200719 /* This might be the optional privateValueLength.
720 * If so, we can cleanly discard it */
721 mbedtls_mpi rec;
722 mbedtls_mpi_init( &rec );
723 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
724 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400725 if ( ret != 0 )
726 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200727 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400728 goto exit;
729 }
730 if ( p != end )
731 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200732 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
733 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400734 goto exit;
735 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200736 }
737
738 ret = 0;
739
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740 dhm->len = mbedtls_mpi_size( &dhm->P );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100741
Paul Bakker40ce79f2013-09-15 17:43:54 +0200742exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743#if defined(MBEDTLS_PEM_PARSE_C)
744 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200745#endif
746 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200748
749 return( ret );
750}
751
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200752#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200753/*
754 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200755 *
756 * The file is expected to contain either PEM or DER encoded data.
757 * A terminating null byte is always appended. It is included in the announced
758 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200759 */
760static int load_file( const char *path, unsigned char **buf, size_t *n )
761{
762 FILE *f;
763 long size;
764
765 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200767
768 fseek( f, 0, SEEK_END );
769 if( ( size = ftell( f ) ) == -1 )
770 {
771 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200773 }
774 fseek( f, 0, SEEK_SET );
775
776 *n = (size_t) size;
777
778 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200779 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200780 {
781 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200782 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200783 }
784
785 if( fread( *buf, 1, *n, f ) != *n )
786 {
787 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_free( *buf );
789 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200790 }
791
792 fclose( f );
793
794 (*buf)[*n] = '\0';
795
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200796 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
797 ++*n;
798
Paul Bakker40ce79f2013-09-15 17:43:54 +0200799 return( 0 );
800}
801
802/*
803 * Load and parse DHM parameters
804 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200806{
807 int ret;
808 size_t n;
809 unsigned char *buf;
810
Paul Bakker66d5d072014-06-17 16:39:18 +0200811 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200812 return( ret );
813
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200814 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200815
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200816 mbedtls_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200818
819 return( ret );
820}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821#endif /* MBEDTLS_FS_IO */
822#endif /* MBEDTLS_ASN1_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200823
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200826static const char mbedtls_test_dhm_params[] =
827"-----BEGIN DH PARAMETERS-----\r\n"
828"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
829"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
830"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
831"-----END DH PARAMETERS-----\r\n";
832
833static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200834
Paul Bakker5121ce52009-01-03 21:22:43 +0000835/*
836 * Checkup routine
837 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000839{
Paul Bakker40ce79f2013-09-15 17:43:54 +0200840 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200842
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200844
Paul Bakker40ce79f2013-09-15 17:43:54 +0200845 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200847
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200848 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
849 (const unsigned char *) mbedtls_test_dhm_params,
850 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200851 {
852 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200854
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200855 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200856 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200857 }
858
859 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200861
Paul Bakker8f870b02014-06-20 13:32:38 +0200862exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200864
Paul Bakker8f870b02014-06-20 13:32:38 +0200865 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000866}
867
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870#endif /* MBEDTLS_DHM_C */