blob: 5a35dfc5503b68c79d62608b02783652620ce836 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <vlib/vlib.h>
17#include <vnet/vnet.h>
18#include <vnet/pg/pg.h>
19#include <vppinfra/error.h>
Dave Barach68b0fb02017-02-28 15:15:56 -050020#include <vnet/udp/udp.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070021#include <vnet/ipsec/ikev2.h>
22#include <vnet/ipsec/ikev2_priv.h>
23#include <openssl/obj_mac.h>
24#include <openssl/ec.h>
25#include <openssl/x509.h>
26#include <openssl/pem.h>
27#include <openssl/bn.h>
Marco Varlesef616d102017-11-09 15:16:20 +010028#include <openssl/dh.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070029
30/* from RFC7296 */
31static const char modp_dh_768_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070032 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
33 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
34 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
35 "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -070036static const char modp_dh_768_generator[] = "02";
37
38static const char modp_dh_1024_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070039 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
40 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
41 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
42 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
43 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" "FFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -070044static const char modp_dh_1024_generator[] = "02";
45
46/* from RFC3526 */
47static const char modp_dh_1536_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070048 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
49 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
50 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
51 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
52 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
53 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
54 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
55 "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -070056static const char modp_dh_1536_generator[] = "02";
57
58static const char modp_dh_2048_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070059 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
60 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
61 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
62 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
63 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
64 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
65 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
66 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
67 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
68 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
69 "15728E5A8AACAA68FFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -070070static const char modp_dh_2048_generator[] = "02";
71
72static const char modp_dh_3072_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070073 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
74 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
75 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
76 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
77 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
78 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
79 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
80 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
81 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
82 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
83 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
84 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
85 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
86 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
87 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
88 "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -070089static const char modp_dh_3072_generator[] = "02";
90
91static const char modp_dh_4096_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070092 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
93 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
94 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
95 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
96 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
97 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
98 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
99 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
100 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
101 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
102 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
103 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
104 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
105 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
106 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
107 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
108 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
109 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
110 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
111 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
112 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" "FFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700113static const char modp_dh_4096_generator[] = "02";
114
115static const char modp_dh_6144_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700116 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
117 "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
118 "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
119 "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
120 "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
121 "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
122 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
123 "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
124 "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
125 "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
126 "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
127 "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
128 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
129 "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
130 "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
131 "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
132 "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
133 "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
134 "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406"
135 "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918"
136 "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151"
137 "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03"
138 "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F"
139 "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
140 "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B"
141 "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632"
142 "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E"
143 "6DCC4024FFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700144static const char modp_dh_6144_generator[] = "02";
145
146static const char modp_dh_8192_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700147 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
148 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
149 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
150 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
151 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
152 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
153 "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
154 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
155 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
156 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
157 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
158 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
159 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
160 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
161 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
162 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
163 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
164 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
165 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
166 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
167 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
168 "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
169 "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
170 "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
171 "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
172 "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
173 "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
174 "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
175 "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
176 "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
177 "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
178 "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
179 "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
180 "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
181 "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
182 "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
183 "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
184 "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
185 "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
186 "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
187 "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
188 "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
189 "60C980DD98EDD3DFFFFFFFFFFFFFFFFF";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190static const char modp_dh_8192_generator[] = "02";
191
192/* from RFC5114 */
193static const char modp_dh_1024_160_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700194 "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
195 "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
196 "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
197 "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
198 "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" "DF1FB2BC2E4A4371";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199static const char modp_dh_1024_160_generator[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700200 "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
201 "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
202 "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
203 "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
204 "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" "855E6EEB22B3B2E5";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700205
206static const char modp_dh_2048_224_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700207 "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1"
208 "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15"
209 "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212"
210 "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207"
211 "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708"
212 "B3BF8A317091883681286130BC8985DB1602E714415D9330"
213 "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D"
214 "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8"
215 "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763"
216 "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71"
217 "CF9DE5384E71B81C0AC4DFFE0C10E64F";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700218static const char modp_dh_2048_224_generator[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700219 "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"
220 "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"
221 "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"
222 "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"
223 "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"
224 "F180EB34118E98D119529A45D6F834566E3025E316A330EF"
225 "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"
226 "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"
227 "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"
228 "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"
229 "81BC087F2A7065B384B890D3191F2BFA";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700230
231static const char modp_dh_2048_256_prime[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700232 "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2"
233 "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30"
234 "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD"
235 "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B"
236 "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C"
237 "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E"
238 "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9"
239 "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026"
240 "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3"
241 "75F26375D7014103A4B54330C198AF126116D2276E11715F"
242 "693877FAD7EF09CADB094AE91E1A1597";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700243static const char modp_dh_2048_256_generator[] =
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700244 "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054"
245 "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555"
246 "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18"
247 "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B"
248 "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83"
249 "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55"
250 "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14"
251 "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915"
252 "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6"
253 "184B523D1DB246C32F63078490F00EF8D647D148D4795451"
254 "5E2327CFEF98C582664B4C0F6CC41659";
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255
256v8 *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700257ikev2_calc_prf (ikev2_sa_transform_t * tr, v8 * key, v8 * data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258{
Marco Varlesef616d102017-11-09 15:16:20 +0100259#if OPENSSL_VERSION_NUMBER >= 0x10100000L
260 HMAC_CTX *ctx;
261#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700262 HMAC_CTX ctx;
Marco Varlesef616d102017-11-09 15:16:20 +0100263#endif
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700264 v8 *prf;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265 unsigned int len = 0;
266
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700267 prf = vec_new (u8, tr->key_trunc);
Marco Varlesef616d102017-11-09 15:16:20 +0100268#if OPENSSL_VERSION_NUMBER >= 0x10100000L
269 ctx = HMAC_CTX_new ();
270 HMAC_Init_ex (ctx, key, vec_len (key), tr->md, NULL);
271 HMAC_Update (ctx, data, vec_len (data));
272 HMAC_Final (ctx, prf, &len);
273#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700274 HMAC_CTX_init (&ctx);
275 HMAC_Init_ex (&ctx, key, vec_len (key), tr->md, NULL);
276 HMAC_Update (&ctx, data, vec_len (data));
277 HMAC_Final (&ctx, prf, &len);
278 HMAC_CTX_cleanup (&ctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100279#endif
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700280 ASSERT (len == tr->key_trunc);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700281
282 return prf;
283}
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700284
Ed Warnickecb9cada2015-12-08 15:45:58 -0700285u8 *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700286ikev2_calc_prfplus (ikev2_sa_transform_t * tr, u8 * key, u8 * seed, int len)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700287{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700288 v8 *t = 0, *s = 0, *tmp = 0, *ret = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700289 u8 x = 0;
290
291 /* prf+ (K,S) = T1 | T2 | T3 | T4 | ...
292
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700293 where:
294 T1 = prf (K, S | 0x01)
295 T2 = prf (K, T1 | S | 0x02)
296 T3 = prf (K, T2 | S | 0x03)
297 T4 = prf (K, T3 | S | 0x04)
298 */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700299
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700300 while (vec_len (ret) < len && x < 255)
301 {
302 if (t)
303 {
304 vec_append (s, t);
305 vec_free (t);
306 }
307
308 vec_append (s, seed);
309 vec_add2 (s, tmp, 1);
310 *tmp = x + 1;
311 t = ikev2_calc_prf (tr, key, s);
312 vec_append (ret, t);
313 vec_free (s);
314 x++;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315 }
316
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700317 vec_free (t);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700318
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700319 if (x == 255)
320 {
321 vec_free (ret);
322 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700323
324 return ret;
325}
326
327v8 *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700328ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data, int len)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700329{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700330 v8 *r;
Marco Varlesef616d102017-11-09 15:16:20 +0100331#if OPENSSL_VERSION_NUMBER >= 0x10100000L
332 HMAC_CTX *hctx;
333#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700334 HMAC_CTX hctx;
Marco Varlesef616d102017-11-09 15:16:20 +0100335#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700336 unsigned int l;
337
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700338 ASSERT (tr->type == IKEV2_TRANSFORM_TYPE_INTEG);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700339
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700340 r = vec_new (u8, tr->key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700341
342 /* verify integrity of data */
Marco Varlesef616d102017-11-09 15:16:20 +0100343#if OPENSSL_VERSION_NUMBER >= 0x10100000L
344 hctx = HMAC_CTX_new ();
345 HMAC_Init_ex (hctx, key, vec_len (key), tr->md, NULL);
346 HMAC_Update (hctx, (const u8 *) data, len);
347 HMAC_Final (hctx, r, &l);
348#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700349 HMAC_CTX_init (&hctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100350 HMAC_Init_ex (&hctx, key, vec_len (key), tr->md, NULL);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700351 HMAC_Update (&hctx, (const u8 *) data, len);
352 HMAC_Final (&hctx, r, &l);
353 HMAC_CTX_cleanup (&hctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100354#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700355
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700356 ASSERT (l == tr->key_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700357
358 return r;
359}
360
361v8 *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700362ikev2_decrypt_data (ikev2_sa_t * sa, u8 * data, int len)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700363{
Marco Varlesef616d102017-11-09 15:16:20 +0100364#if OPENSSL_VERSION_NUMBER >= 0x10100000L
365 EVP_CIPHER_CTX *ctx;
366#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700367 EVP_CIPHER_CTX ctx;
Marco Varlesef616d102017-11-09 15:16:20 +0100368#endif
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700369 v8 *r;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700370 int out_len = 0, block_size;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700371 ikev2_sa_transform_t *tr_encr;
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000372 u8 *key = sa->is_initiator ? sa->sk_er : sa->sk_ei;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700373
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700374 tr_encr =
375 ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700376 block_size = tr_encr->block_size;
377
378 /* check if data is multiplier of cipher block size */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700379 if (len % block_size)
380 {
381 clib_warning ("wrong data length");
382 return 0;
383 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700384
Marco Varlesef616d102017-11-09 15:16:20 +0100385#if OPENSSL_VERSION_NUMBER >= 0x10100000L
386 ctx = EVP_CIPHER_CTX_new ();
387#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700388 EVP_CIPHER_CTX_init (&ctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100389#endif
390
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700391 r = vec_new (u8, len - block_size);
Marco Varlesef616d102017-11-09 15:16:20 +0100392
393#if OPENSSL_VERSION_NUMBER >= 0x10100000L
394 EVP_DecryptInit_ex (ctx, tr_encr->cipher, NULL, key, data);
395 EVP_DecryptUpdate (ctx, r, &out_len, data + block_size, len - block_size);
396 EVP_DecryptFinal_ex (ctx, r + out_len, &out_len);
397#else
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000398 EVP_DecryptInit_ex (&ctx, tr_encr->cipher, NULL, key, data);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700399 EVP_DecryptUpdate (&ctx, r, &out_len, data + block_size, len - block_size);
400 EVP_DecryptFinal_ex (&ctx, r + out_len, &out_len);
Marco Varlesef616d102017-11-09 15:16:20 +0100401#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700402 /* remove padding */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700403 _vec_len (r) -= r[vec_len (r) - 1] + 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700404
Marco Varlesef616d102017-11-09 15:16:20 +0100405#if OPENSSL_VERSION_NUMBER < 0x10100000L
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700406 EVP_CIPHER_CTX_cleanup (&ctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100407#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700408 return r;
409}
410
411int
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700412ikev2_encrypt_data (ikev2_sa_t * sa, v8 * src, u8 * dst)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700413{
Marco Varlesef616d102017-11-09 15:16:20 +0100414#if OPENSSL_VERSION_NUMBER >= 0x10100000L
415 EVP_CIPHER_CTX *ctx;
416#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700417 EVP_CIPHER_CTX ctx;
Marco Varlesef616d102017-11-09 15:16:20 +0100418#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700419 int out_len;
420 int bs;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700421 ikev2_sa_transform_t *tr_encr;
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000422 u8 *key = sa->is_initiator ? sa->sk_ei : sa->sk_er;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700424 tr_encr =
425 ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700426 bs = tr_encr->block_size;
427
428 /* generate IV */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700429 RAND_bytes (dst, bs);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700430
Marco Varlesef616d102017-11-09 15:16:20 +0100431#if OPENSSL_VERSION_NUMBER >= 0x10100000L
432 ctx = EVP_CIPHER_CTX_new ();
433 EVP_EncryptInit_ex (ctx, tr_encr->cipher, NULL, key, dst /* dst */ );
434 EVP_EncryptUpdate (ctx, dst + bs, &out_len, src, vec_len (src));
435#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700436 EVP_CIPHER_CTX_init (&ctx);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000437 EVP_EncryptInit_ex (&ctx, tr_encr->cipher, NULL, key, dst /* dst */ );
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700438 EVP_EncryptUpdate (&ctx, dst + bs, &out_len, src, vec_len (src));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700439 EVP_CIPHER_CTX_cleanup (&ctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100440#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700441
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700442 ASSERT (vec_len (src) == out_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700443
444 return out_len + bs;
445}
446
447void
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700448ikev2_generate_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700449{
450 int r;
Marco Varlesef616d102017-11-09 15:16:20 +0100451#if OPENSSL_VERSION_NUMBER >= 0x10100000L
452 BIGNUM *p = BN_new ();
453 BIGNUM *q = BN_new ();
454 BIGNUM *g = BN_new ();
455 BIGNUM *pub_key = BN_new ();
456 BIGNUM *priv_key = BN_new ();
457#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700458
459 if (t->dh_group == IKEV2_DH_GROUP_MODP)
460 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700461 DH *dh = DH_new ();
Marco Varlesef616d102017-11-09 15:16:20 +0100462#if OPENSSL_VERSION_NUMBER >= 0x10100000L
463 BN_hex2bn (&p, t->dh_p);
464 BN_hex2bn (&g, t->dh_g);
465 DH_set0_pqg (dh, p, q, g);
466#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700467 BN_hex2bn (&dh->p, t->dh_p);
468 BN_hex2bn (&dh->g, t->dh_g);
Marco Varlesef616d102017-11-09 15:16:20 +0100469#endif
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700470 DH_generate_key (dh);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700471
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000472 if (sa->is_initiator)
473 {
474 sa->i_dh_data = vec_new (u8, t->key_len);
Marco Varlesef616d102017-11-09 15:16:20 +0100475 sa->dh_private_key = vec_new (u8, t->key_len);
476#if OPENSSL_VERSION_NUMBER >= 0x10100000L
477 r = BN_bn2bin (pub_key, sa->i_dh_data);
478 ASSERT (r == t->key_len);
479 r = BN_bn2bin (priv_key, sa->dh_private_key);
480 DH_set0_key (dh, pub_key, priv_key);
481#else
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000482 r = BN_bn2bin (dh->pub_key, sa->i_dh_data);
483 ASSERT (r == t->key_len);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000484 r = BN_bn2bin (dh->priv_key, sa->dh_private_key);
485 ASSERT (r == t->key_len);
Marco Varlesef616d102017-11-09 15:16:20 +0100486#endif
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000487 }
488 else
489 {
490 sa->r_dh_data = vec_new (u8, t->key_len);
Marco Varlesef616d102017-11-09 15:16:20 +0100491#if OPENSSL_VERSION_NUMBER >= 0x10100000L
492 r = BN_bn2bin (pub_key, sa->i_dh_data);
493 ASSERT (r == t->key_len);
494 DH_set0_key (dh, pub_key, NULL);
495#else
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000496 r = BN_bn2bin (dh->pub_key, sa->r_dh_data);
497 ASSERT (r == t->key_len);
Marco Varlesef616d102017-11-09 15:16:20 +0100498#endif
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000499 BIGNUM *ex;
500 sa->dh_shared_key = vec_new (u8, t->key_len);
501 ex = BN_bin2bn (sa->i_dh_data, vec_len (sa->i_dh_data), NULL);
502 r = DH_compute_key (sa->dh_shared_key, ex, dh);
503 ASSERT (r == t->key_len);
504 BN_clear_free (ex);
505 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700506 DH_free (dh);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700507 }
508 else if (t->dh_group == IKEV2_DH_GROUP_ECP)
509 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700510 EC_KEY *ec = EC_KEY_new_by_curve_name (t->nid);
511 ASSERT (ec);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700512
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700513 EC_KEY_generate_key (ec);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700514
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700515 const EC_POINT *r_point = EC_KEY_get0_public_key (ec);
516 const EC_GROUP *group = EC_KEY_get0_group (ec);
517 BIGNUM *x = NULL, *y = NULL;
518 BN_CTX *bn_ctx = BN_CTX_new ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700519 u16 x_off, y_off, len;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700520 EC_POINT *i_point = EC_POINT_new (group);
521 EC_POINT *shared_point = EC_POINT_new (group);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700522
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700523 x = BN_new ();
524 y = BN_new ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700525 len = t->key_len / 2;
526
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700527 EC_POINT_get_affine_coordinates_GFp (group, r_point, x, y, bn_ctx);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000528
529 if (sa->is_initiator)
530 {
531 sa->i_dh_data = vec_new (u8, t->key_len);
532 x_off = len - BN_num_bytes (x);
533 memset (sa->i_dh_data, 0, x_off);
534 BN_bn2bin (x, sa->i_dh_data + x_off);
535 y_off = t->key_len - BN_num_bytes (y);
536 memset (sa->i_dh_data + len, 0, y_off - len);
537 BN_bn2bin (y, sa->i_dh_data + y_off);
538
539 const BIGNUM *prv = EC_KEY_get0_private_key (ec);
540 sa->dh_private_key = vec_new (u8, BN_num_bytes (prv));
541 r = BN_bn2bin (prv, sa->dh_private_key);
542 ASSERT (r == BN_num_bytes (prv));
543 }
544 else
545 {
546 sa->r_dh_data = vec_new (u8, t->key_len);
547 x_off = len - BN_num_bytes (x);
548 memset (sa->r_dh_data, 0, x_off);
549 BN_bn2bin (x, sa->r_dh_data + x_off);
550 y_off = t->key_len - BN_num_bytes (y);
551 memset (sa->r_dh_data + len, 0, y_off - len);
552 BN_bn2bin (y, sa->r_dh_data + y_off);
553
554 x = BN_bin2bn (sa->i_dh_data, len, x);
555 y = BN_bin2bn (sa->i_dh_data + len, len, y);
556 EC_POINT_set_affine_coordinates_GFp (group, i_point, x, y, bn_ctx);
557 sa->dh_shared_key = vec_new (u8, t->key_len);
558 EC_POINT_mul (group, shared_point, NULL, i_point,
559 EC_KEY_get0_private_key (ec), NULL);
560 EC_POINT_get_affine_coordinates_GFp (group, shared_point, x, y,
561 bn_ctx);
562 x_off = len - BN_num_bytes (x);
563 memset (sa->dh_shared_key, 0, x_off);
564 BN_bn2bin (x, sa->dh_shared_key + x_off);
565 y_off = t->key_len - BN_num_bytes (y);
566 memset (sa->dh_shared_key + len, 0, y_off - len);
567 BN_bn2bin (y, sa->dh_shared_key + y_off);
568 }
569
570 EC_KEY_free (ec);
571 BN_free (x);
572 BN_free (y);
573 BN_CTX_free (bn_ctx);
574 EC_POINT_free (i_point);
575 EC_POINT_free (shared_point);
576 }
577}
578
579void
580ikev2_complete_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t)
581{
582 int r;
Marco Varlesef616d102017-11-09 15:16:20 +0100583#if OPENSSL_VERSION_NUMBER >= 0x10100000L
584 BIGNUM *p = BN_new ();
585 BIGNUM *q = BN_new ();
586 BIGNUM *g = BN_new ();
587 BIGNUM *priv_key = BN_new ();
588#endif
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000589
590 if (t->dh_group == IKEV2_DH_GROUP_MODP)
591 {
592 DH *dh = DH_new ();
Marco Varlesef616d102017-11-09 15:16:20 +0100593#if OPENSSL_VERSION_NUMBER >= 0x10100000L
594 BN_hex2bn (&p, t->dh_p);
595 BN_hex2bn (&g, t->dh_g);
596 DH_set0_pqg (dh, p, q, g);
597
598 priv_key =
599 BN_bin2bn (sa->dh_private_key, vec_len (sa->dh_private_key), NULL);
600 DH_set0_key (dh, NULL, priv_key);
601#else
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000602 BN_hex2bn (&dh->p, t->dh_p);
603 BN_hex2bn (&dh->g, t->dh_g);
Marco Varlesef616d102017-11-09 15:16:20 +0100604
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000605 dh->priv_key =
606 BN_bin2bn (sa->dh_private_key, vec_len (sa->dh_private_key), NULL);
Marco Varlesef616d102017-11-09 15:16:20 +0100607#endif
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000608 BIGNUM *ex;
609 sa->dh_shared_key = vec_new (u8, t->key_len);
610 ex = BN_bin2bn (sa->r_dh_data, vec_len (sa->r_dh_data), NULL);
611 r = DH_compute_key (sa->dh_shared_key, ex, dh);
612 ASSERT (r == t->key_len);
613 BN_clear_free (ex);
614 DH_free (dh);
615 }
616 else if (t->dh_group == IKEV2_DH_GROUP_ECP)
617 {
618 EC_KEY *ec = EC_KEY_new_by_curve_name (t->nid);
619 ASSERT (ec);
620
621 const EC_GROUP *group = EC_KEY_get0_group (ec);
622 BIGNUM *x = NULL, *y = NULL;
623 BN_CTX *bn_ctx = BN_CTX_new ();
624 u16 x_off, y_off, len;
625 BIGNUM *prv;
626
627 prv =
628 BN_bin2bn (sa->dh_private_key, vec_len (sa->dh_private_key), NULL);
629 EC_KEY_set_private_key (ec, prv);
630
631 x = BN_new ();
632 y = BN_new ();
633 len = t->key_len / 2;
634
635 x = BN_bin2bn (sa->r_dh_data, len, x);
636 y = BN_bin2bn (sa->r_dh_data + len, len, y);
637 EC_POINT *r_point = EC_POINT_new (group);
638 EC_POINT_set_affine_coordinates_GFp (group, r_point, x, y, bn_ctx);
639 EC_KEY_set_public_key (ec, r_point);
640
641 EC_POINT *i_point = EC_POINT_new (group);
642 EC_POINT *shared_point = EC_POINT_new (group);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700643
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700644 x = BN_bin2bn (sa->i_dh_data, len, x);
645 y = BN_bin2bn (sa->i_dh_data + len, len, y);
646 EC_POINT_set_affine_coordinates_GFp (group, i_point, x, y, bn_ctx);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000647 EC_POINT_mul (group, shared_point, NULL, r_point,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700648 EC_KEY_get0_private_key (ec), NULL);
649 EC_POINT_get_affine_coordinates_GFp (group, shared_point, x, y, bn_ctx);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000650 sa->dh_shared_key = vec_new (u8, t->key_len);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700651 x_off = len - BN_num_bytes (x);
652 memset (sa->dh_shared_key, 0, x_off);
653 BN_bn2bin (x, sa->dh_shared_key + x_off);
654 y_off = t->key_len - BN_num_bytes (y);
655 memset (sa->dh_shared_key + len, 0, y_off - len);
656 BN_bn2bin (y, sa->dh_shared_key + y_off);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700657
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700658 EC_KEY_free (ec);
659 BN_free (x);
660 BN_free (y);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000661 BN_free (prv);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700662 BN_CTX_free (bn_ctx);
663 EC_POINT_free (i_point);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000664 EC_POINT_free (r_point);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700665 EC_POINT_free (shared_point);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700666 }
667}
668
669int
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700670ikev2_verify_sign (EVP_PKEY * pkey, u8 * sigbuf, u8 * data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700671{
Marco Varlesef616d102017-11-09 15:16:20 +0100672#if OPENSSL_VERSION_NUMBER >= 0x10100000L
673 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new ();
674#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700675 EVP_MD_CTX md_ctx;
Radu Nicolauf706b8d2018-05-29 11:42:33 +0100676 EVP_MD_CTX_init (&md_ctx);
Marco Varlesef616d102017-11-09 15:16:20 +0100677#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700678
Marco Varlesef616d102017-11-09 15:16:20 +0100679#if OPENSSL_VERSION_NUMBER >= 0x10100000L
680 EVP_VerifyInit (md_ctx, EVP_sha1 ());
681 EVP_VerifyUpdate (md_ctx, data, vec_len (data));
682#else
683 EVP_VerifyInit_ex (&md_ctx, EVP_sha1 (), NULL);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700684 EVP_VerifyUpdate (&md_ctx, data, vec_len (data));
Marco Varlesef616d102017-11-09 15:16:20 +0100685#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700686
Marco Varlesef616d102017-11-09 15:16:20 +0100687#if OPENSSL_VERSION_NUMBER >= 0x10100000L
688 return EVP_VerifyFinal (md_ctx, sigbuf, vec_len (sigbuf), pkey);
689#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700690 return EVP_VerifyFinal (&md_ctx, sigbuf, vec_len (sigbuf), pkey);
Marco Varlesef616d102017-11-09 15:16:20 +0100691#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700692}
693
694u8 *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700695ikev2_calc_sign (EVP_PKEY * pkey, u8 * data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700696{
Marco Varlesef616d102017-11-09 15:16:20 +0100697#if OPENSSL_VERSION_NUMBER >= 0x10100000L
698 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new ();
699#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700700 EVP_MD_CTX md_ctx;
Marco Varlesef616d102017-11-09 15:16:20 +0100701#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700702 unsigned int sig_len = 0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700703 u8 *sign;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700704
Marco Varlesef616d102017-11-09 15:16:20 +0100705#if OPENSSL_VERSION_NUMBER >= 0x10100000L
706 EVP_SignInit (md_ctx, EVP_sha1 ());
707 EVP_SignUpdate (md_ctx, data, vec_len (data));
708 /* get sign len */
709 EVP_SignFinal (md_ctx, NULL, &sig_len, pkey);
710 sign = vec_new (u8, sig_len);
711 /* calc sign */
712 EVP_SignFinal (md_ctx, sign, &sig_len, pkey);
713#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700714 EVP_SignInit (&md_ctx, EVP_sha1 ());
715 EVP_SignUpdate (&md_ctx, data, vec_len (data));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700716 /* get sign len */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700717 EVP_SignFinal (&md_ctx, NULL, &sig_len, pkey);
718 sign = vec_new (u8, sig_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700719 /* calc sign */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700720 EVP_SignFinal (&md_ctx, sign, &sig_len, pkey);
Marco Varlesef616d102017-11-09 15:16:20 +0100721#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700722 return sign;
723}
724
725EVP_PKEY *
726ikev2_load_cert_file (u8 * file)
727{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700728 FILE *fp;
729 X509 *x509;
730 EVP_PKEY *pkey = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700731
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700732 fp = fopen ((char *) file, "r");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700733 if (!fp)
734 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700735 clib_warning ("open %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700736 goto end;
737 }
738
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700739 x509 = PEM_read_X509 (fp, NULL, NULL, NULL);
740 fclose (fp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700741 if (x509 == NULL)
742 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700743 clib_warning ("read cert %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700744 goto end;
745 }
746
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700747 pkey = X509_get_pubkey (x509);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700748 if (pkey == NULL)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700749 clib_warning ("get pubkey %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700750
751end:
752 return pkey;
753}
754
755EVP_PKEY *
756ikev2_load_key_file (u8 * file)
757{
758 FILE *fp;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700759 EVP_PKEY *pkey = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700760
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700761 fp = fopen ((char *) file, "r");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700762 if (!fp)
763 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700764 clib_warning ("open %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700765 goto end;
766 }
767
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700768 pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL);
769 fclose (fp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700770 if (pkey == NULL)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700771 clib_warning ("read %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700772
773end:
774 return pkey;
775}
776
777void
778ikev2_crypto_init (ikev2_main_t * km)
779{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700780 ikev2_sa_transform_t *tr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700781
782 /* vector of supported transforms - in order of preference */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700783 vec_add2 (km->supported_transforms, tr, 1);
784 tr->type = IKEV2_TRANSFORM_TYPE_ENCR;
785 tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC;
786 tr->key_len = 256 / 8;
787 tr->block_size = 128 / 8;
788 tr->cipher = EVP_aes_256_cbc ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700789
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700790 vec_add2 (km->supported_transforms, tr, 1);
791 tr->type = IKEV2_TRANSFORM_TYPE_ENCR;
792 tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC;
793 tr->key_len = 192 / 8;
794 tr->block_size = 128 / 8;
795 tr->cipher = EVP_aes_192_cbc ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700796
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700797 vec_add2 (km->supported_transforms, tr, 1);
798 tr->type = IKEV2_TRANSFORM_TYPE_ENCR;
799 tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC;
800 tr->key_len = 128 / 8;
801 tr->block_size = 128 / 8;
802 tr->cipher = EVP_aes_128_cbc ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700803
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700804 vec_add2 (km->supported_transforms, tr, 1);
805 tr->type = IKEV2_TRANSFORM_TYPE_PRF;
806 tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1;
807 tr->key_len = 160 / 8;
808 tr->key_trunc = 160 / 8;
809 tr->md = EVP_sha1 ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700810
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700811 vec_add2 (km->supported_transforms, tr, 1);
812 tr->type = IKEV2_TRANSFORM_TYPE_INTEG;
813 tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96;
814 tr->key_len = 160 / 8;
815 tr->key_trunc = 96 / 8;
816 tr->md = EVP_sha1 ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700817
818#if defined(OPENSSL_NO_CISCO_FECDH)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700819 vec_add2 (km->supported_transforms, tr, 1);
820 tr->type = IKEV2_TRANSFORM_TYPE_DH;
821 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_512;
822 tr->key_len = (512 * 2) / 8;
823 tr->nid = NID_brainpoolP512r1;
824 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700825
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700826 vec_add2 (km->supported_transforms, tr, 1);
827 tr->type = IKEV2_TRANSFORM_TYPE_DH;
828 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_384;
829 tr->key_len = (384 * 2) / 8;
830 tr->nid = NID_brainpoolP384r1;
831 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700832
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700833 vec_add2 (km->supported_transforms, tr, 1);
834 tr->type = IKEV2_TRANSFORM_TYPE_DH;
835 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_256;
836 tr->key_len = (256 * 2) / 8;
837 tr->nid = NID_brainpoolP256r1;
838 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700839
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700840 vec_add2 (km->supported_transforms, tr, 1);
841 tr->type = IKEV2_TRANSFORM_TYPE_DH;
842 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_224;
843 tr->key_len = (224 * 2) / 8;
844 tr->nid = NID_brainpoolP224r1;
845 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700846
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700847 vec_add2 (km->supported_transforms, tr, 1);
848 tr->type = IKEV2_TRANSFORM_TYPE_DH;
849 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_224;
850 tr->key_len = (224 * 2) / 8;
851 tr->nid = NID_secp224r1;
852 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700853#endif
854
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700855 vec_add2 (km->supported_transforms, tr, 1);
856 tr->type = IKEV2_TRANSFORM_TYPE_DH;
857 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_521;
858 tr->key_len = (528 * 2) / 8;
859 tr->nid = NID_secp521r1;
860 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700861
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700862 vec_add2 (km->supported_transforms, tr, 1);
863 tr->type = IKEV2_TRANSFORM_TYPE_DH;
864 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_384;
865 tr->key_len = (384 * 2) / 8;
866 tr->nid = NID_secp384r1;
867 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700868
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700869 vec_add2 (km->supported_transforms, tr, 1);
870 tr->type = IKEV2_TRANSFORM_TYPE_DH;
871 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_256;
872 tr->key_len = (256 * 2) / 8;
873 tr->nid = NID_X9_62_prime256v1;
874 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700875
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700876 vec_add2 (km->supported_transforms, tr, 1);
877 tr->type = IKEV2_TRANSFORM_TYPE_DH;
878 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_192;
879 tr->key_len = (192 * 2) / 8;
880 tr->nid = NID_X9_62_prime192v1;
881 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700882
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700883 vec_add2 (km->supported_transforms, tr, 1);
884 tr->type = IKEV2_TRANSFORM_TYPE_DH;
885 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_256;
886 tr->key_len = 2048 / 8;
887 tr->dh_p = (const char *) &modp_dh_2048_256_prime;
888 tr->dh_g = (const char *) &modp_dh_2048_256_generator;
889 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700890
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700891 vec_add2 (km->supported_transforms, tr, 1);
892 tr->type = IKEV2_TRANSFORM_TYPE_DH;
893 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_224;
894 tr->key_len = 2048 / 8;
895 tr->dh_p = (const char *) &modp_dh_2048_224_prime;
896 tr->dh_g = (const char *) &modp_dh_2048_224_generator;
897 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700898
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700899 vec_add2 (km->supported_transforms, tr, 1);
900 tr->type = IKEV2_TRANSFORM_TYPE_DH;
901 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024_160;
902 tr->key_len = 1024 / 8;
903 tr->dh_p = (const char *) &modp_dh_1024_160_prime;
904 tr->dh_g = (const char *) &modp_dh_1024_160_generator;
905 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700906
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700907 vec_add2 (km->supported_transforms, tr, 1);
908 tr->type = IKEV2_TRANSFORM_TYPE_DH;
909 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_8192;
910 tr->key_len = 8192 / 8;
911 tr->dh_p = (const char *) &modp_dh_8192_prime;
912 tr->dh_g = (const char *) &modp_dh_8192_generator;
913 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700914
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700915 vec_add2 (km->supported_transforms, tr, 1);
916 tr->type = IKEV2_TRANSFORM_TYPE_DH;
917 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_6144;
918 tr->key_len = 6144 / 8;
919 tr->dh_p = (const char *) &modp_dh_6144_prime;
920 tr->dh_g = (const char *) &modp_dh_6144_generator;
921 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700922
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700923 vec_add2 (km->supported_transforms, tr, 1);
924 tr->type = IKEV2_TRANSFORM_TYPE_DH;
925 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_4096;
926 tr->key_len = 4096 / 8;
927 tr->dh_p = (const char *) &modp_dh_4096_prime;
928 tr->dh_g = (const char *) &modp_dh_4096_generator;
929 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700930
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700931 vec_add2 (km->supported_transforms, tr, 1);
932 tr->type = IKEV2_TRANSFORM_TYPE_DH;
933 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_3072;
934 tr->key_len = 3072 / 8;
935 tr->dh_p = (const char *) &modp_dh_3072_prime;
936 tr->dh_g = (const char *) &modp_dh_3072_generator;
937 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700938
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700939 vec_add2 (km->supported_transforms, tr, 1);
940 tr->type = IKEV2_TRANSFORM_TYPE_DH;
941 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048;
942 tr->key_len = 2048 / 8;
943 tr->dh_p = (const char *) &modp_dh_2048_prime;
944 tr->dh_g = (const char *) &modp_dh_2048_generator;
945 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700946
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700947 vec_add2 (km->supported_transforms, tr, 1);
948 tr->type = IKEV2_TRANSFORM_TYPE_DH;
949 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1536;
950 tr->key_len = 1536 / 8;
951 tr->dh_p = (const char *) &modp_dh_1536_prime;
952 tr->dh_g = (const char *) &modp_dh_1536_generator;
953 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700954
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700955 vec_add2 (km->supported_transforms, tr, 1);
956 tr->type = IKEV2_TRANSFORM_TYPE_DH;
957 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024;
958 tr->key_len = 1024 / 8;
959 tr->dh_p = (const char *) &modp_dh_1024_prime;
960 tr->dh_g = (const char *) &modp_dh_1024_generator;
961 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700962
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700963 vec_add2 (km->supported_transforms, tr, 1);
964 tr->type = IKEV2_TRANSFORM_TYPE_DH;
965 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_768;
966 tr->key_len = 768 / 8;
967 tr->dh_p = (const char *) &modp_dh_768_prime;
968 tr->dh_g = (const char *) &modp_dh_768_generator;
969 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700970
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700971 vec_add2 (km->supported_transforms, tr, 1);
972 tr->type = IKEV2_TRANSFORM_TYPE_ESN;
973 tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_ESN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700974
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700975 vec_add2 (km->supported_transforms, tr, 1);
976 tr->type = IKEV2_TRANSFORM_TYPE_ESN;
977 tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_NO_ESN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700978}
979
980
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700981
982/*
983 * fd.io coding-style-patch-verification: ON
984 *
985 * Local Variables:
986 * eval: (c-set-style "gnu")
987 * End:
988 */