xref: /openbsd/sbin/iked/dh.c (revision c900656b)
1*c900656bSmarkus /*	$OpenBSD: dh.c,v 1.11 2013/11/14 12:30:35 markus Exp $	*/
245ae9d61Sreyk 
345ae9d61Sreyk /*
4fcebd35dSreyk  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
545ae9d61Sreyk  *
645ae9d61Sreyk  * Permission to use, copy, modify, and distribute this software for any
745ae9d61Sreyk  * purpose with or without fee is hereby granted, provided that the above
845ae9d61Sreyk  * copyright notice and this permission notice appear in all copies.
945ae9d61Sreyk  *
1045ae9d61Sreyk  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1145ae9d61Sreyk  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1245ae9d61Sreyk  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1345ae9d61Sreyk  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1445ae9d61Sreyk  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1545ae9d61Sreyk  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1645ae9d61Sreyk  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1745ae9d61Sreyk  */
1845ae9d61Sreyk 
1945ae9d61Sreyk #include <sys/param.h>
2045ae9d61Sreyk #include <string.h>
2145ae9d61Sreyk 
2245ae9d61Sreyk #include <openssl/obj_mac.h>
2345ae9d61Sreyk #include <openssl/dh.h>
2445ae9d61Sreyk #include <openssl/ec.h>
2545ae9d61Sreyk #include <openssl/ecdh.h>
2645ae9d61Sreyk 
2745ae9d61Sreyk #include "dh.h"
280d5bf58dSreyk 
290d5bf58dSreyk int	dh_init(struct group *);
3045ae9d61Sreyk 
3145ae9d61Sreyk int	modp_init(struct group *);
3245ae9d61Sreyk int	modp_getlen(struct group *);
3345ae9d61Sreyk int	modp_create_exchange(struct group *, u_int8_t *);
3445ae9d61Sreyk int	modp_create_shared(struct group *, u_int8_t *, u_int8_t *);
3545ae9d61Sreyk 
3645ae9d61Sreyk int	ec_init(struct group *);
3745ae9d61Sreyk int	ec_getlen(struct group *);
3845ae9d61Sreyk int	ec_create_exchange(struct group *, u_int8_t *);
3945ae9d61Sreyk int	ec_create_shared(struct group *, u_int8_t *, u_int8_t *);
4045ae9d61Sreyk 
4145ae9d61Sreyk int	ec_point2raw(struct group *, const EC_POINT *, u_int8_t *, size_t);
4245ae9d61Sreyk EC_POINT *
4345ae9d61Sreyk 	ec_raw2point(struct group *, u_int8_t *, size_t);
4445ae9d61Sreyk 
4545ae9d61Sreyk struct group_id ike_groups[] = {
4645ae9d61Sreyk 	{ GROUP_MODP, 1, 768,
4745ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
4845ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
4945ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
5045ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF",
5145ae9d61Sreyk 	    "02"
5245ae9d61Sreyk 	},
5345ae9d61Sreyk 	{ GROUP_MODP, 2, 1024,
5445ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
5545ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
5645ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
5745ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
5845ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
5945ae9d61Sreyk 	    "FFFFFFFFFFFFFFFF",
6045ae9d61Sreyk 	    "02"
6145ae9d61Sreyk 	},
62369beec1Sreyk 	{ GROUP_EC2N, 3, 155, NULL, NULL, NID_ipsec3 },
63369beec1Sreyk 	{ GROUP_EC2N, 4, 185, NULL, NULL, NID_ipsec4 },
6445ae9d61Sreyk 	{ GROUP_MODP, 5, 1536,
6545ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
6645ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
6745ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
6845ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
6945ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
7045ae9d61Sreyk 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
7145ae9d61Sreyk 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
7245ae9d61Sreyk 	    "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
7345ae9d61Sreyk 	    "02"
7445ae9d61Sreyk 	},
7545ae9d61Sreyk 	{ GROUP_MODP, 14, 2048,
7645ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
7745ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
7845ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
7945ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
8045ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
8145ae9d61Sreyk 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
8245ae9d61Sreyk 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
8345ae9d61Sreyk 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
8445ae9d61Sreyk 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
8545ae9d61Sreyk 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
8645ae9d61Sreyk 	    "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
8745ae9d61Sreyk 	    "02"
8845ae9d61Sreyk 	},
8945ae9d61Sreyk 	{ GROUP_MODP, 15, 3072,
9045ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
9145ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
9245ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
9345ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
9445ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
9545ae9d61Sreyk 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
9645ae9d61Sreyk 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
9745ae9d61Sreyk 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
9845ae9d61Sreyk 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
9945ae9d61Sreyk 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
10045ae9d61Sreyk 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
10145ae9d61Sreyk 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
10245ae9d61Sreyk 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
10345ae9d61Sreyk 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
10445ae9d61Sreyk 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
10545ae9d61Sreyk 	    "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
10645ae9d61Sreyk 	    "02"
10745ae9d61Sreyk 	},
10845ae9d61Sreyk 	{ GROUP_MODP, 16, 4096,
10945ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
11045ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
11145ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
11245ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
11345ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
11445ae9d61Sreyk 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
11545ae9d61Sreyk 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
11645ae9d61Sreyk 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
11745ae9d61Sreyk 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
11845ae9d61Sreyk 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
11945ae9d61Sreyk 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
12045ae9d61Sreyk 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
12145ae9d61Sreyk 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
12245ae9d61Sreyk 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
12345ae9d61Sreyk 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
12445ae9d61Sreyk 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
12545ae9d61Sreyk 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
12645ae9d61Sreyk 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
12745ae9d61Sreyk 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
12845ae9d61Sreyk 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
12945ae9d61Sreyk 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
13045ae9d61Sreyk 	    "FFFFFFFFFFFFFFFF",
13145ae9d61Sreyk 	    "02"
13245ae9d61Sreyk 	},
13345ae9d61Sreyk 	{ GROUP_MODP, 17, 6144,
13445ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
13545ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
13645ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
13745ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
13845ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
13945ae9d61Sreyk 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
14045ae9d61Sreyk 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
14145ae9d61Sreyk 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
14245ae9d61Sreyk 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
14345ae9d61Sreyk 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
14445ae9d61Sreyk 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
14545ae9d61Sreyk 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
14645ae9d61Sreyk 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
14745ae9d61Sreyk 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
14845ae9d61Sreyk 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
14945ae9d61Sreyk 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
15045ae9d61Sreyk 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
15145ae9d61Sreyk 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
15245ae9d61Sreyk 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
15345ae9d61Sreyk 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
15445ae9d61Sreyk 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
15545ae9d61Sreyk 	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
15645ae9d61Sreyk 	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
15745ae9d61Sreyk 	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
15845ae9d61Sreyk 	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
15945ae9d61Sreyk 	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
16045ae9d61Sreyk 	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
16145ae9d61Sreyk 	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
16245ae9d61Sreyk 	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
16345ae9d61Sreyk 	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
16445ae9d61Sreyk 	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
16545ae9d61Sreyk 	    "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF",
16645ae9d61Sreyk 	    "02"
16745ae9d61Sreyk 	},
16845ae9d61Sreyk 	{ GROUP_MODP, 18, 8192,
16945ae9d61Sreyk 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
17045ae9d61Sreyk 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
17145ae9d61Sreyk 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
17245ae9d61Sreyk 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
17345ae9d61Sreyk 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
17445ae9d61Sreyk 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
17545ae9d61Sreyk 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
17645ae9d61Sreyk 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
17745ae9d61Sreyk 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
17845ae9d61Sreyk 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
17945ae9d61Sreyk 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
18045ae9d61Sreyk 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
18145ae9d61Sreyk 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
18245ae9d61Sreyk 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
18345ae9d61Sreyk 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
18445ae9d61Sreyk 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
18545ae9d61Sreyk 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
18645ae9d61Sreyk 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
18745ae9d61Sreyk 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
18845ae9d61Sreyk 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
18945ae9d61Sreyk 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
19045ae9d61Sreyk 	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
19145ae9d61Sreyk 	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
19245ae9d61Sreyk 	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
19345ae9d61Sreyk 	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
19445ae9d61Sreyk 	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
19545ae9d61Sreyk 	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
19645ae9d61Sreyk 	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
19745ae9d61Sreyk 	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
19845ae9d61Sreyk 	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
19945ae9d61Sreyk 	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
20045ae9d61Sreyk 	    "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
20145ae9d61Sreyk 	    "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
20245ae9d61Sreyk 	    "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
20345ae9d61Sreyk 	    "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
20445ae9d61Sreyk 	    "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
20545ae9d61Sreyk 	    "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
20645ae9d61Sreyk 	    "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
20745ae9d61Sreyk 	    "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
20845ae9d61Sreyk 	    "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
20945ae9d61Sreyk 	    "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
21045ae9d61Sreyk 	    "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
21145ae9d61Sreyk 	    "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
21245ae9d61Sreyk 	    "02"
21345ae9d61Sreyk 	},
214369beec1Sreyk 	{ GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 },
215369beec1Sreyk 	{ GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 },
216369beec1Sreyk 	{ GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 },
21745ae9d61Sreyk 	{ GROUP_MODP, 22, 1024,
21845ae9d61Sreyk 	    "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
21945ae9d61Sreyk 	    "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
22045ae9d61Sreyk 	    "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
22145ae9d61Sreyk 	    "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
22245ae9d61Sreyk 	    "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
22345ae9d61Sreyk 	    "DF1FB2BC2E4A4371",
22445ae9d61Sreyk 	    "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
22545ae9d61Sreyk 	    "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
22645ae9d61Sreyk 	    "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
22745ae9d61Sreyk 	    "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
22845ae9d61Sreyk 	    "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
22945ae9d61Sreyk 	    "855E6EEB22B3B2E5"
23045ae9d61Sreyk 	},
23145ae9d61Sreyk 	{ GROUP_MODP, 23, 2048,
23245ae9d61Sreyk 	    "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1"
23345ae9d61Sreyk 	    "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15"
23445ae9d61Sreyk 	    "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212"
23545ae9d61Sreyk 	    "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207"
23645ae9d61Sreyk 	    "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708"
23745ae9d61Sreyk 	    "B3BF8A317091883681286130BC8985DB1602E714415D9330"
23845ae9d61Sreyk 	    "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D"
23945ae9d61Sreyk 	    "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8"
24045ae9d61Sreyk 	    "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763"
24145ae9d61Sreyk 	    "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71"
24245ae9d61Sreyk 	    "CF9DE5384E71B81C0AC4DFFE0C10E64F",
24345ae9d61Sreyk 	    "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"
24445ae9d61Sreyk 	    "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"
24545ae9d61Sreyk 	    "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"
24645ae9d61Sreyk 	    "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"
24745ae9d61Sreyk 	    "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"
24845ae9d61Sreyk 	    "F180EB34118E98D119529A45D6F834566E3025E316A330EF"
24945ae9d61Sreyk 	    "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"
25045ae9d61Sreyk 	    "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"
25145ae9d61Sreyk 	    "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"
25245ae9d61Sreyk 	    "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"
25345ae9d61Sreyk 	    "81BC087F2A7065B384B890D3191F2BFA"
25445ae9d61Sreyk 	},
25545ae9d61Sreyk 	{ GROUP_MODP, 24, 2048,
25645ae9d61Sreyk 	    "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2"
25745ae9d61Sreyk 	    "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30"
25845ae9d61Sreyk 	    "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD"
25945ae9d61Sreyk 	    "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B"
26045ae9d61Sreyk 	    "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C"
26145ae9d61Sreyk 	    "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E"
26245ae9d61Sreyk 	    "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9"
26345ae9d61Sreyk 	    "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026"
26445ae9d61Sreyk 	    "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3"
26545ae9d61Sreyk 	    "75F26375D7014103A4B54330C198AF126116D2276E11715F"
26645ae9d61Sreyk 	    "693877FAD7EF09CADB094AE91E1A1597",
26745ae9d61Sreyk 	    "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054"
26845ae9d61Sreyk 	    "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555"
26945ae9d61Sreyk 	    "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18"
27045ae9d61Sreyk 	    "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B"
27145ae9d61Sreyk 	    "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83"
27245ae9d61Sreyk 	    "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55"
27345ae9d61Sreyk 	    "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14"
27445ae9d61Sreyk 	    "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915"
27545ae9d61Sreyk 	    "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6"
27645ae9d61Sreyk 	    "184B523D1DB246C32F63078490F00EF8D647D148D4795451"
27745ae9d61Sreyk 	    "5E2327CFEF98C582664B4C0F6CC41659"
27845ae9d61Sreyk 	},
279369beec1Sreyk 	{ GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 },
280369beec1Sreyk 	{ GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 }
28145ae9d61Sreyk };
28245ae9d61Sreyk 
28345ae9d61Sreyk void
28445ae9d61Sreyk group_init(void)
28545ae9d61Sreyk {
2860d5bf58dSreyk 	/* currently not used */
28745ae9d61Sreyk 	return;
28845ae9d61Sreyk }
28945ae9d61Sreyk 
29045ae9d61Sreyk void
29145ae9d61Sreyk group_free(struct group *group)
29245ae9d61Sreyk {
29345ae9d61Sreyk 	if (group == NULL)
29445ae9d61Sreyk 		return;
29545ae9d61Sreyk 	if (group->dh != NULL)
29645ae9d61Sreyk 		DH_free(group->dh);
29745ae9d61Sreyk 	if (group->ec != NULL)
29845ae9d61Sreyk 		EC_KEY_free(group->ec);
29945ae9d61Sreyk 	group->spec = NULL;
30064449014Sreyk 	free(group);
30145ae9d61Sreyk }
30245ae9d61Sreyk 
30345ae9d61Sreyk struct group *
30445ae9d61Sreyk group_get(u_int32_t id)
30545ae9d61Sreyk {
30645ae9d61Sreyk 	struct group_id	*p = NULL;
30745ae9d61Sreyk 	struct group	*group;
30845ae9d61Sreyk 	u_int		 i, items;
30945ae9d61Sreyk 
31045ae9d61Sreyk 	items = sizeof(ike_groups) / sizeof(ike_groups[0]);
31145ae9d61Sreyk 	for (i = 0; i < items; i++) {
31245ae9d61Sreyk 		if (id == ike_groups[i].id) {
31345ae9d61Sreyk 			p = &ike_groups[i];
31445ae9d61Sreyk 			break;
31545ae9d61Sreyk 		}
31645ae9d61Sreyk 	}
31745ae9d61Sreyk 	if (p == NULL)
31845ae9d61Sreyk 		return (NULL);
31945ae9d61Sreyk 
32045ae9d61Sreyk 	if ((group = calloc(1, sizeof(*group))) == NULL)
32145ae9d61Sreyk 		return (NULL);
32245ae9d61Sreyk 
32345ae9d61Sreyk 	group->id = id;
32445ae9d61Sreyk 	group->spec = p;
32545ae9d61Sreyk 
32645ae9d61Sreyk 	switch (p->type) {
32745ae9d61Sreyk 	case GROUP_MODP:
32845ae9d61Sreyk 		group->init = modp_init;
32945ae9d61Sreyk 		group->getlen = modp_getlen;
33045ae9d61Sreyk 		group->exchange = modp_create_exchange;
33145ae9d61Sreyk 		group->shared = modp_create_shared;
33245ae9d61Sreyk 		break;
333369beec1Sreyk 	case GROUP_EC2N:
334369beec1Sreyk 	case GROUP_ECP:
33545ae9d61Sreyk 		group->init = ec_init;
33645ae9d61Sreyk 		group->getlen = ec_getlen;
33745ae9d61Sreyk 		group->exchange = ec_create_exchange;
33845ae9d61Sreyk 		group->shared = ec_create_shared;
33945ae9d61Sreyk 		break;
34045ae9d61Sreyk 	default:
34145ae9d61Sreyk 		group_free(group);
34245ae9d61Sreyk 		return (NULL);
34345ae9d61Sreyk 	}
34445ae9d61Sreyk 
34545ae9d61Sreyk 	if (dh_init(group) != 0) {
34645ae9d61Sreyk 		group_free(group);
34745ae9d61Sreyk 		return (NULL);
34845ae9d61Sreyk 	}
34945ae9d61Sreyk 
35045ae9d61Sreyk 	return (group);
35145ae9d61Sreyk }
35245ae9d61Sreyk 
35345ae9d61Sreyk int
35445ae9d61Sreyk dh_init(struct group *group)
35545ae9d61Sreyk {
35645ae9d61Sreyk 	return (group->init(group));
35745ae9d61Sreyk }
35845ae9d61Sreyk 
35945ae9d61Sreyk int
36045ae9d61Sreyk dh_getlen(struct group *group)
36145ae9d61Sreyk {
36245ae9d61Sreyk 	return (group->getlen(group));
36345ae9d61Sreyk }
36445ae9d61Sreyk 
36545ae9d61Sreyk int
36645ae9d61Sreyk dh_create_exchange(struct group *group, u_int8_t *buf)
36745ae9d61Sreyk {
36845ae9d61Sreyk 	return (group->exchange(group, buf));
36945ae9d61Sreyk }
37045ae9d61Sreyk 
37145ae9d61Sreyk int
37245ae9d61Sreyk dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
37345ae9d61Sreyk {
37445ae9d61Sreyk 	return (group->shared(group, secret, exchange));
37545ae9d61Sreyk }
37645ae9d61Sreyk 
37745ae9d61Sreyk int
37845ae9d61Sreyk modp_init(struct group *group)
37945ae9d61Sreyk {
38045ae9d61Sreyk 	DH	*dh;
38145ae9d61Sreyk 
38245ae9d61Sreyk 	if ((dh = DH_new()) == NULL)
38345ae9d61Sreyk 		return (-1);
3847d7b0856Sreyk 	group->dh = dh;
38545ae9d61Sreyk 
38645ae9d61Sreyk 	if (!BN_hex2bn(&dh->p, group->spec->prime) ||
38745ae9d61Sreyk 	    !BN_hex2bn(&dh->g, group->spec->generator))
38845ae9d61Sreyk 		return (-1);
38945ae9d61Sreyk 
39045ae9d61Sreyk 	return (0);
39145ae9d61Sreyk }
39245ae9d61Sreyk 
39345ae9d61Sreyk int
39445ae9d61Sreyk modp_getlen(struct group *group)
39545ae9d61Sreyk {
39645ae9d61Sreyk 	if (group->spec == NULL)
39745ae9d61Sreyk 		return (0);
39845ae9d61Sreyk 	return (roundup(group->spec->bits, 8) / 8);
39945ae9d61Sreyk }
40045ae9d61Sreyk 
40145ae9d61Sreyk int
40245ae9d61Sreyk modp_create_exchange(struct group *group, u_int8_t *buf)
40345ae9d61Sreyk {
40445ae9d61Sreyk 	DH	*dh = group->dh;
40512abf43bSmikeb 	int	 len, ret;
40645ae9d61Sreyk 
40745ae9d61Sreyk 	if (!DH_generate_key(dh))
40845ae9d61Sreyk 		return (-1);
40912abf43bSmikeb 	ret = BN_bn2bin(dh->pub_key, buf);
41012abf43bSmikeb 	if (!ret)
41145ae9d61Sreyk 		return (-1);
41245ae9d61Sreyk 
41312abf43bSmikeb 	len = dh_getlen(group);
41412abf43bSmikeb 
41512abf43bSmikeb 	/* add zero padding */
41612abf43bSmikeb 	if (ret < len) {
41712abf43bSmikeb 		bcopy(buf, buf + (len - ret), ret);
41812abf43bSmikeb 		bzero(buf, len - ret);
41912abf43bSmikeb 	}
42012abf43bSmikeb 
4217d7b0856Sreyk 	return (0);
42245ae9d61Sreyk }
42345ae9d61Sreyk 
42445ae9d61Sreyk int
42545ae9d61Sreyk modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
42645ae9d61Sreyk {
42745ae9d61Sreyk 	BIGNUM	*ex;
42812abf43bSmikeb 	int	 len, ret;
42945ae9d61Sreyk 
43012abf43bSmikeb 	len = dh_getlen(group);
43112abf43bSmikeb 
43212abf43bSmikeb 	if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL)
43345ae9d61Sreyk 		return (-1);
4347d7b0856Sreyk 
4357d7b0856Sreyk 	ret = DH_compute_key(secret, ex, group->dh);
4367d7b0856Sreyk 	BN_clear_free(ex);
4377d7b0856Sreyk 	if (!ret)
43845ae9d61Sreyk 		return (-1);
43945ae9d61Sreyk 
44012abf43bSmikeb 	/* add zero padding */
44112abf43bSmikeb 	if (ret < len) {
44212abf43bSmikeb 		bcopy(secret, secret + (len - ret), ret);
44312abf43bSmikeb 		bzero(secret, len - ret);
44412abf43bSmikeb 	}
44512abf43bSmikeb 
4467d7b0856Sreyk 	return (0);
44745ae9d61Sreyk }
44845ae9d61Sreyk 
44945ae9d61Sreyk int
45045ae9d61Sreyk ec_init(struct group *group)
45145ae9d61Sreyk {
45245ae9d61Sreyk 	if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL)
45345ae9d61Sreyk 		return (-1);
45445ae9d61Sreyk 	if (!EC_KEY_generate_key(group->ec))
45545ae9d61Sreyk 		return (-1);
456*c900656bSmarkus 	if (!EC_KEY_check_key(group->ec)) {
457*c900656bSmarkus 		EC_KEY_free(group->ec);
458*c900656bSmarkus 		return (-1);
459*c900656bSmarkus 	}
46045ae9d61Sreyk 	return (0);
46145ae9d61Sreyk }
46245ae9d61Sreyk 
46345ae9d61Sreyk int
46445ae9d61Sreyk ec_getlen(struct group *group)
46545ae9d61Sreyk {
46645ae9d61Sreyk 	if (group->spec == NULL)
46745ae9d61Sreyk 		return (0);
46845b72fd1Smikeb 	/* NB:  Return value will always be even */
46945ae9d61Sreyk 	return ((roundup(group->spec->bits, 8) * 2) / 8);
47045ae9d61Sreyk }
47145ae9d61Sreyk 
47245ae9d61Sreyk int
47345ae9d61Sreyk ec_create_exchange(struct group *group, u_int8_t *buf)
47445ae9d61Sreyk {
4750d5bf58dSreyk 	size_t	 len;
4760d5bf58dSreyk 
4770d5bf58dSreyk 	len = ec_getlen(group);
4780d5bf58dSreyk 	bzero(buf, len);
4790d5bf58dSreyk 
48045ae9d61Sreyk 	return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec),
4810d5bf58dSreyk 	    buf, len));
48245ae9d61Sreyk }
48345ae9d61Sreyk 
48445ae9d61Sreyk int
48545ae9d61Sreyk ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
48645ae9d61Sreyk {
48745ae9d61Sreyk 	const EC_GROUP	*ecgroup = NULL;
48845ae9d61Sreyk 	const BIGNUM	*privkey;
489*c900656bSmarkus 	EC_KEY		*exkey = NULL;
49045ae9d61Sreyk 	EC_POINT	*exchangep = NULL, *secretp = NULL;
49145ae9d61Sreyk 	int		 ret = -1;
49245ae9d61Sreyk 
49345ae9d61Sreyk 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL ||
49445ae9d61Sreyk 	    (privkey = EC_KEY_get0_private_key(group->ec)) == NULL)
49545ae9d61Sreyk 		goto done;
49645ae9d61Sreyk 
49745ae9d61Sreyk 	if ((exchangep =
49845ae9d61Sreyk 	    ec_raw2point(group, exchange, ec_getlen(group))) == NULL)
49945ae9d61Sreyk 		goto done;
50045ae9d61Sreyk 
501*c900656bSmarkus 	if ((exkey = EC_KEY_new()) == NULL)
502*c900656bSmarkus 		goto done;
503*c900656bSmarkus 	if (!EC_KEY_set_group(exkey, ecgroup))
504*c900656bSmarkus 		goto done;
505*c900656bSmarkus 	if (!EC_KEY_set_public_key(exkey, exchangep))
506*c900656bSmarkus 		goto done;
507*c900656bSmarkus 
508*c900656bSmarkus 	/* validate exchangep */
509*c900656bSmarkus 	if (!EC_KEY_check_key(exkey))
510*c900656bSmarkus 		goto done;
511*c900656bSmarkus 
51245ae9d61Sreyk 	if ((secretp = EC_POINT_new(ecgroup)) == NULL)
51345ae9d61Sreyk 		goto done;
51445ae9d61Sreyk 
51545ae9d61Sreyk 	if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL))
51645ae9d61Sreyk 		goto done;
51745ae9d61Sreyk 
51845ae9d61Sreyk 	ret = ec_point2raw(group, secretp, secret, ec_getlen(group));
51945ae9d61Sreyk 
52045ae9d61Sreyk  done:
521*c900656bSmarkus 	if (exkey != NULL)
522*c900656bSmarkus 		EC_KEY_free(exkey);
52345ae9d61Sreyk 	if (exchangep != NULL)
52445ae9d61Sreyk 		EC_POINT_clear_free(exchangep);
52545ae9d61Sreyk 	if (secretp != NULL)
52645ae9d61Sreyk 		EC_POINT_clear_free(secretp);
52745ae9d61Sreyk 
52845ae9d61Sreyk 	return (ret);
52945ae9d61Sreyk }
53045ae9d61Sreyk 
53145ae9d61Sreyk int
53245ae9d61Sreyk ec_point2raw(struct group *group, const EC_POINT *point,
53345ae9d61Sreyk     u_int8_t *buf, size_t len)
53445ae9d61Sreyk {
53545ae9d61Sreyk 	const EC_GROUP	*ecgroup = NULL;
53645ae9d61Sreyk 	BN_CTX		*bnctx = NULL;
53745ae9d61Sreyk 	BIGNUM		*x = NULL, *y = NULL;
53845ae9d61Sreyk 	int		 ret = -1;
53945b72fd1Smikeb 	size_t		 eclen, xlen, ylen;
54045ae9d61Sreyk 	off_t		 xoff, yoff;
54145ae9d61Sreyk 
54245ae9d61Sreyk 	if ((bnctx = BN_CTX_new()) == NULL)
54345ae9d61Sreyk 		goto done;
54445ae9d61Sreyk 	BN_CTX_start(bnctx);
54545ae9d61Sreyk 	if ((x = BN_CTX_get(bnctx)) == NULL ||
54645ae9d61Sreyk 	    (y = BN_CTX_get(bnctx)) == NULL)
54745ae9d61Sreyk 		goto done;
54845ae9d61Sreyk 
54945b72fd1Smikeb 	eclen = ec_getlen(group);
55045b72fd1Smikeb 	if (len < eclen)
55145b72fd1Smikeb 		goto done;
55245b72fd1Smikeb 	xlen = ylen = eclen / 2;
55345b72fd1Smikeb 
55445ae9d61Sreyk 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
55545ae9d61Sreyk 		goto done;
55645ae9d61Sreyk 
55745ae9d61Sreyk 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
55845ae9d61Sreyk 	    NID_X9_62_prime_field) {
55945ae9d61Sreyk 		if (!EC_POINT_get_affine_coordinates_GFp(ecgroup,
56045ae9d61Sreyk 		    point, x, y, bnctx))
56145ae9d61Sreyk 			goto done;
56245ae9d61Sreyk 	} else {
56345ae9d61Sreyk 		if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup,
56445ae9d61Sreyk 		    point, x, y, bnctx))
56545ae9d61Sreyk 			goto done;
56645ae9d61Sreyk 	}
56745ae9d61Sreyk 
56845ae9d61Sreyk 	xoff = xlen - BN_num_bytes(x);
56945b72fd1Smikeb 	bzero(buf, xoff);
57045ae9d61Sreyk 	if (!BN_bn2bin(x, buf + xoff))
57145ae9d61Sreyk 		goto done;
57245ae9d61Sreyk 
57345ae9d61Sreyk 	yoff = (ylen - BN_num_bytes(y)) + xlen;
57445b72fd1Smikeb 	bzero(buf + xlen, yoff - xlen);
57545ae9d61Sreyk 	if (!BN_bn2bin(y, buf + yoff))
57645ae9d61Sreyk 		goto done;
57745ae9d61Sreyk 
57845ae9d61Sreyk 	ret = 0;
57945ae9d61Sreyk  done:
580*c900656bSmarkus 	/* Make sure to erase sensitive data */
581*c900656bSmarkus 	if (x != NULL)
582*c900656bSmarkus 		BN_clear(x);
583*c900656bSmarkus 	if (y != NULL)
584*c900656bSmarkus 		BN_clear(y);
58545ae9d61Sreyk 	BN_CTX_end(bnctx);
58645ae9d61Sreyk 	BN_CTX_free(bnctx);
58745ae9d61Sreyk 
58845ae9d61Sreyk 	return (ret);
58945ae9d61Sreyk }
59045ae9d61Sreyk 
59145ae9d61Sreyk EC_POINT *
59245ae9d61Sreyk ec_raw2point(struct group *group, u_int8_t *buf, size_t len)
59345ae9d61Sreyk {
59445ae9d61Sreyk 	const EC_GROUP	*ecgroup = NULL;
59545ae9d61Sreyk 	EC_POINT	*point = NULL;
59645ae9d61Sreyk 	BN_CTX		*bnctx = NULL;
59745ae9d61Sreyk 	BIGNUM		*x = NULL, *y = NULL;
59845ae9d61Sreyk 	int		 ret = -1;
59945ae9d61Sreyk 	size_t		 eclen;
60045ae9d61Sreyk 	size_t		 xlen, ylen;
60145ae9d61Sreyk 
60245ae9d61Sreyk 	if ((bnctx = BN_CTX_new()) == NULL)
60345ae9d61Sreyk 		goto done;
60445ae9d61Sreyk 	BN_CTX_start(bnctx);
60545ae9d61Sreyk 	if ((x = BN_CTX_get(bnctx)) == NULL ||
60645ae9d61Sreyk 	    (y = BN_CTX_get(bnctx)) == NULL)
60745ae9d61Sreyk 		goto done;
60845ae9d61Sreyk 
60945ae9d61Sreyk 	eclen = ec_getlen(group);
61045ae9d61Sreyk 	if (len < eclen)
61145ae9d61Sreyk 		goto done;
61245ae9d61Sreyk 	xlen = ylen = eclen / 2;
61345ae9d61Sreyk 	if ((x = BN_bin2bn(buf, xlen, x)) == NULL ||
61445ae9d61Sreyk 	    (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL)
61545ae9d61Sreyk 		goto done;
61645ae9d61Sreyk 
61745ae9d61Sreyk 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
61845ae9d61Sreyk 		goto done;
61945ae9d61Sreyk 
62045ae9d61Sreyk 	if ((point = EC_POINT_new(ecgroup)) == NULL)
62145ae9d61Sreyk 		goto done;
62245ae9d61Sreyk 
62345ae9d61Sreyk 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
62445ae9d61Sreyk 	    NID_X9_62_prime_field) {
62545ae9d61Sreyk 		if (!EC_POINT_set_affine_coordinates_GFp(ecgroup,
62645ae9d61Sreyk 		    point, x, y, bnctx))
62745ae9d61Sreyk 			goto done;
62845ae9d61Sreyk 	} else {
62945ae9d61Sreyk 		if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup,
63045ae9d61Sreyk 		    point, x, y, bnctx))
63145ae9d61Sreyk 			goto done;
63245ae9d61Sreyk 	}
63345ae9d61Sreyk 
63445ae9d61Sreyk 	ret = 0;
63545ae9d61Sreyk  done:
63645ae9d61Sreyk 	if (ret != 0 && point != NULL)
63745ae9d61Sreyk 		EC_POINT_clear_free(point);
638*c900656bSmarkus 	/* Make sure to erase sensitive data */
639*c900656bSmarkus 	if (x != NULL)
640*c900656bSmarkus 		BN_clear(x);
641*c900656bSmarkus 	if (y != NULL)
642*c900656bSmarkus 		BN_clear(y);
64345ae9d61Sreyk 	BN_CTX_end(bnctx);
64445ae9d61Sreyk 	BN_CTX_free(bnctx);
64545ae9d61Sreyk 
64645ae9d61Sreyk 	return (point);
64745ae9d61Sreyk }
648