blob: 32e687e37c0c5c728a904b0ae8fd84fe9aeeafda [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;
Marco Varlesef616d102017-11-09 15:16:20 +0100676#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700677
Marco Varlesef616d102017-11-09 15:16:20 +0100678#if OPENSSL_VERSION_NUMBER >= 0x10100000L
679 EVP_VerifyInit (md_ctx, EVP_sha1 ());
680 EVP_VerifyUpdate (md_ctx, data, vec_len (data));
681#else
682 EVP_VerifyInit_ex (&md_ctx, EVP_sha1 (), NULL);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700683 EVP_VerifyUpdate (&md_ctx, data, vec_len (data));
Marco Varlesef616d102017-11-09 15:16:20 +0100684#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700685
Marco Varlesef616d102017-11-09 15:16:20 +0100686#if OPENSSL_VERSION_NUMBER >= 0x10100000L
687 return EVP_VerifyFinal (md_ctx, sigbuf, vec_len (sigbuf), pkey);
688#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700689 return EVP_VerifyFinal (&md_ctx, sigbuf, vec_len (sigbuf), pkey);
Marco Varlesef616d102017-11-09 15:16:20 +0100690#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700691}
692
693u8 *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700694ikev2_calc_sign (EVP_PKEY * pkey, u8 * data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700695{
Marco Varlesef616d102017-11-09 15:16:20 +0100696#if OPENSSL_VERSION_NUMBER >= 0x10100000L
697 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new ();
698#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700699 EVP_MD_CTX md_ctx;
Marco Varlesef616d102017-11-09 15:16:20 +0100700#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700701 unsigned int sig_len = 0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700702 u8 *sign;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700703
Marco Varlesef616d102017-11-09 15:16:20 +0100704#if OPENSSL_VERSION_NUMBER >= 0x10100000L
705 EVP_SignInit (md_ctx, EVP_sha1 ());
706 EVP_SignUpdate (md_ctx, data, vec_len (data));
707 /* get sign len */
708 EVP_SignFinal (md_ctx, NULL, &sig_len, pkey);
709 sign = vec_new (u8, sig_len);
710 /* calc sign */
711 EVP_SignFinal (md_ctx, sign, &sig_len, pkey);
712#else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700713 EVP_SignInit (&md_ctx, EVP_sha1 ());
714 EVP_SignUpdate (&md_ctx, data, vec_len (data));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700715 /* get sign len */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700716 EVP_SignFinal (&md_ctx, NULL, &sig_len, pkey);
717 sign = vec_new (u8, sig_len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700718 /* calc sign */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700719 EVP_SignFinal (&md_ctx, sign, &sig_len, pkey);
Marco Varlesef616d102017-11-09 15:16:20 +0100720#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700721 return sign;
722}
723
724EVP_PKEY *
725ikev2_load_cert_file (u8 * file)
726{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700727 FILE *fp;
728 X509 *x509;
729 EVP_PKEY *pkey = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700730
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700731 fp = fopen ((char *) file, "r");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700732 if (!fp)
733 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700734 clib_warning ("open %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700735 goto end;
736 }
737
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700738 x509 = PEM_read_X509 (fp, NULL, NULL, NULL);
739 fclose (fp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700740 if (x509 == NULL)
741 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700742 clib_warning ("read cert %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700743 goto end;
744 }
745
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700746 pkey = X509_get_pubkey (x509);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700747 if (pkey == NULL)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700748 clib_warning ("get pubkey %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700749
750end:
751 return pkey;
752}
753
754EVP_PKEY *
755ikev2_load_key_file (u8 * file)
756{
757 FILE *fp;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700758 EVP_PKEY *pkey = NULL;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700759
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700760 fp = fopen ((char *) file, "r");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700761 if (!fp)
762 {
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700763 clib_warning ("open %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700764 goto end;
765 }
766
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700767 pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL);
768 fclose (fp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700769 if (pkey == NULL)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700770 clib_warning ("read %s failed", file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700771
772end:
773 return pkey;
774}
775
776void
777ikev2_crypto_init (ikev2_main_t * km)
778{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700779 ikev2_sa_transform_t *tr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700780
781 /* vector of supported transforms - in order of preference */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700782 vec_add2 (km->supported_transforms, tr, 1);
783 tr->type = IKEV2_TRANSFORM_TYPE_ENCR;
784 tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC;
785 tr->key_len = 256 / 8;
786 tr->block_size = 128 / 8;
787 tr->cipher = EVP_aes_256_cbc ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700788
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700789 vec_add2 (km->supported_transforms, tr, 1);
790 tr->type = IKEV2_TRANSFORM_TYPE_ENCR;
791 tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC;
792 tr->key_len = 192 / 8;
793 tr->block_size = 128 / 8;
794 tr->cipher = EVP_aes_192_cbc ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700795
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700796 vec_add2 (km->supported_transforms, tr, 1);
797 tr->type = IKEV2_TRANSFORM_TYPE_ENCR;
798 tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC;
799 tr->key_len = 128 / 8;
800 tr->block_size = 128 / 8;
801 tr->cipher = EVP_aes_128_cbc ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700802
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700803 vec_add2 (km->supported_transforms, tr, 1);
804 tr->type = IKEV2_TRANSFORM_TYPE_PRF;
805 tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1;
806 tr->key_len = 160 / 8;
807 tr->key_trunc = 160 / 8;
808 tr->md = EVP_sha1 ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700809
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700810 vec_add2 (km->supported_transforms, tr, 1);
811 tr->type = IKEV2_TRANSFORM_TYPE_INTEG;
812 tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96;
813 tr->key_len = 160 / 8;
814 tr->key_trunc = 96 / 8;
815 tr->md = EVP_sha1 ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700816
817#if defined(OPENSSL_NO_CISCO_FECDH)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700818 vec_add2 (km->supported_transforms, tr, 1);
819 tr->type = IKEV2_TRANSFORM_TYPE_DH;
820 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_512;
821 tr->key_len = (512 * 2) / 8;
822 tr->nid = NID_brainpoolP512r1;
823 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700824
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700825 vec_add2 (km->supported_transforms, tr, 1);
826 tr->type = IKEV2_TRANSFORM_TYPE_DH;
827 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_384;
828 tr->key_len = (384 * 2) / 8;
829 tr->nid = NID_brainpoolP384r1;
830 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700831
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700832 vec_add2 (km->supported_transforms, tr, 1);
833 tr->type = IKEV2_TRANSFORM_TYPE_DH;
834 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_256;
835 tr->key_len = (256 * 2) / 8;
836 tr->nid = NID_brainpoolP256r1;
837 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700838
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700839 vec_add2 (km->supported_transforms, tr, 1);
840 tr->type = IKEV2_TRANSFORM_TYPE_DH;
841 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_BRAINPOOL_224;
842 tr->key_len = (224 * 2) / 8;
843 tr->nid = NID_brainpoolP224r1;
844 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700845
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700846 vec_add2 (km->supported_transforms, tr, 1);
847 tr->type = IKEV2_TRANSFORM_TYPE_DH;
848 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_224;
849 tr->key_len = (224 * 2) / 8;
850 tr->nid = NID_secp224r1;
851 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700852#endif
853
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700854 vec_add2 (km->supported_transforms, tr, 1);
855 tr->type = IKEV2_TRANSFORM_TYPE_DH;
856 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_521;
857 tr->key_len = (528 * 2) / 8;
858 tr->nid = NID_secp521r1;
859 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700860
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700861 vec_add2 (km->supported_transforms, tr, 1);
862 tr->type = IKEV2_TRANSFORM_TYPE_DH;
863 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_384;
864 tr->key_len = (384 * 2) / 8;
865 tr->nid = NID_secp384r1;
866 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700867
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700868 vec_add2 (km->supported_transforms, tr, 1);
869 tr->type = IKEV2_TRANSFORM_TYPE_DH;
870 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_256;
871 tr->key_len = (256 * 2) / 8;
872 tr->nid = NID_X9_62_prime256v1;
873 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700874
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700875 vec_add2 (km->supported_transforms, tr, 1);
876 tr->type = IKEV2_TRANSFORM_TYPE_DH;
877 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_ECP_192;
878 tr->key_len = (192 * 2) / 8;
879 tr->nid = NID_X9_62_prime192v1;
880 tr->dh_group = IKEV2_DH_GROUP_ECP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700881
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700882 vec_add2 (km->supported_transforms, tr, 1);
883 tr->type = IKEV2_TRANSFORM_TYPE_DH;
884 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_256;
885 tr->key_len = 2048 / 8;
886 tr->dh_p = (const char *) &modp_dh_2048_256_prime;
887 tr->dh_g = (const char *) &modp_dh_2048_256_generator;
888 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700889
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700890 vec_add2 (km->supported_transforms, tr, 1);
891 tr->type = IKEV2_TRANSFORM_TYPE_DH;
892 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048_224;
893 tr->key_len = 2048 / 8;
894 tr->dh_p = (const char *) &modp_dh_2048_224_prime;
895 tr->dh_g = (const char *) &modp_dh_2048_224_generator;
896 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700897
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700898 vec_add2 (km->supported_transforms, tr, 1);
899 tr->type = IKEV2_TRANSFORM_TYPE_DH;
900 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024_160;
901 tr->key_len = 1024 / 8;
902 tr->dh_p = (const char *) &modp_dh_1024_160_prime;
903 tr->dh_g = (const char *) &modp_dh_1024_160_generator;
904 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700905
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700906 vec_add2 (km->supported_transforms, tr, 1);
907 tr->type = IKEV2_TRANSFORM_TYPE_DH;
908 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_8192;
909 tr->key_len = 8192 / 8;
910 tr->dh_p = (const char *) &modp_dh_8192_prime;
911 tr->dh_g = (const char *) &modp_dh_8192_generator;
912 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700913
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700914 vec_add2 (km->supported_transforms, tr, 1);
915 tr->type = IKEV2_TRANSFORM_TYPE_DH;
916 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_6144;
917 tr->key_len = 6144 / 8;
918 tr->dh_p = (const char *) &modp_dh_6144_prime;
919 tr->dh_g = (const char *) &modp_dh_6144_generator;
920 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700921
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700922 vec_add2 (km->supported_transforms, tr, 1);
923 tr->type = IKEV2_TRANSFORM_TYPE_DH;
924 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_4096;
925 tr->key_len = 4096 / 8;
926 tr->dh_p = (const char *) &modp_dh_4096_prime;
927 tr->dh_g = (const char *) &modp_dh_4096_generator;
928 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700929
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700930 vec_add2 (km->supported_transforms, tr, 1);
931 tr->type = IKEV2_TRANSFORM_TYPE_DH;
932 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_3072;
933 tr->key_len = 3072 / 8;
934 tr->dh_p = (const char *) &modp_dh_3072_prime;
935 tr->dh_g = (const char *) &modp_dh_3072_generator;
936 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700937
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700938 vec_add2 (km->supported_transforms, tr, 1);
939 tr->type = IKEV2_TRANSFORM_TYPE_DH;
940 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_2048;
941 tr->key_len = 2048 / 8;
942 tr->dh_p = (const char *) &modp_dh_2048_prime;
943 tr->dh_g = (const char *) &modp_dh_2048_generator;
944 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700945
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700946 vec_add2 (km->supported_transforms, tr, 1);
947 tr->type = IKEV2_TRANSFORM_TYPE_DH;
948 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1536;
949 tr->key_len = 1536 / 8;
950 tr->dh_p = (const char *) &modp_dh_1536_prime;
951 tr->dh_g = (const char *) &modp_dh_1536_generator;
952 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700953
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700954 vec_add2 (km->supported_transforms, tr, 1);
955 tr->type = IKEV2_TRANSFORM_TYPE_DH;
956 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_1024;
957 tr->key_len = 1024 / 8;
958 tr->dh_p = (const char *) &modp_dh_1024_prime;
959 tr->dh_g = (const char *) &modp_dh_1024_generator;
960 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700961
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700962 vec_add2 (km->supported_transforms, tr, 1);
963 tr->type = IKEV2_TRANSFORM_TYPE_DH;
964 tr->dh_type = IKEV2_TRANSFORM_DH_TYPE_MODP_768;
965 tr->key_len = 768 / 8;
966 tr->dh_p = (const char *) &modp_dh_768_prime;
967 tr->dh_g = (const char *) &modp_dh_768_generator;
968 tr->dh_group = IKEV2_DH_GROUP_MODP;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700969
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700970 vec_add2 (km->supported_transforms, tr, 1);
971 tr->type = IKEV2_TRANSFORM_TYPE_ESN;
972 tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_ESN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700973
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700974 vec_add2 (km->supported_transforms, tr, 1);
975 tr->type = IKEV2_TRANSFORM_TYPE_ESN;
976 tr->esn_type = IKEV2_TRANSFORM_ESN_TYPE_NO_ESN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700977}
978
979
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700980
981/*
982 * fd.io coding-style-patch-verification: ON
983 *
984 * Local Variables:
985 * eval: (c-set-style "gnu")
986 * End:
987 */