1*7d7b0856Sreyk /* $OpenBSD: dh.c,v 1.4 2010/06/29 19:38:26 reyk Exp $ */ 245ae9d61Sreyk /* $vantronix: dh.c,v 1.13 2010/05/28 15:34:35 reyk Exp $ */ 345ae9d61Sreyk 445ae9d61Sreyk /* 545ae9d61Sreyk * Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net> 645ae9d61Sreyk * 745ae9d61Sreyk * Permission to use, copy, modify, and distribute this software for any 845ae9d61Sreyk * purpose with or without fee is hereby granted, provided that the above 945ae9d61Sreyk * copyright notice and this permission notice appear in all copies. 1045ae9d61Sreyk * 1145ae9d61Sreyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1245ae9d61Sreyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1345ae9d61Sreyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1445ae9d61Sreyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1545ae9d61Sreyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1645ae9d61Sreyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1745ae9d61Sreyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1845ae9d61Sreyk */ 1945ae9d61Sreyk 2045ae9d61Sreyk #include <sys/param.h> 2145ae9d61Sreyk #include <string.h> 2245ae9d61Sreyk 2345ae9d61Sreyk #include <openssl/obj_mac.h> 2445ae9d61Sreyk #include <openssl/dh.h> 2545ae9d61Sreyk #include <openssl/ec.h> 2645ae9d61Sreyk #include <openssl/ecdh.h> 2745ae9d61Sreyk 2845ae9d61Sreyk #include "dh.h" 290d5bf58dSreyk 300d5bf58dSreyk int dh_init(struct group *); 3145ae9d61Sreyk 3245ae9d61Sreyk int modp_init(struct group *); 3345ae9d61Sreyk int modp_getlen(struct group *); 3445ae9d61Sreyk int modp_create_exchange(struct group *, u_int8_t *); 3545ae9d61Sreyk int modp_create_shared(struct group *, u_int8_t *, u_int8_t *); 3645ae9d61Sreyk 3745ae9d61Sreyk int ec_init(struct group *); 3845ae9d61Sreyk int ec_getlen(struct group *); 3945ae9d61Sreyk int ec_create_exchange(struct group *, u_int8_t *); 4045ae9d61Sreyk int ec_create_shared(struct group *, u_int8_t *, u_int8_t *); 4145ae9d61Sreyk 4245ae9d61Sreyk int ec_point2raw(struct group *, const EC_POINT *, u_int8_t *, size_t); 4345ae9d61Sreyk EC_POINT * 4445ae9d61Sreyk ec_raw2point(struct group *, u_int8_t *, size_t); 4545ae9d61Sreyk 4645ae9d61Sreyk struct group_id ike_groups[] = { 4745ae9d61Sreyk { GROUP_MODP, 1, 768, 4845ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 4945ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 5045ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 5145ae9d61Sreyk "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 5245ae9d61Sreyk "02" 5345ae9d61Sreyk }, 5445ae9d61Sreyk { GROUP_MODP, 2, 1024, 5545ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 5645ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 5745ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 5845ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 5945ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" 6045ae9d61Sreyk "FFFFFFFFFFFFFFFF", 6145ae9d61Sreyk "02" 6245ae9d61Sreyk }, 63369beec1Sreyk { GROUP_EC2N, 3, 155, NULL, NULL, NID_ipsec3 }, 64369beec1Sreyk { GROUP_EC2N, 4, 185, NULL, NULL, NID_ipsec4 }, 6545ae9d61Sreyk { GROUP_MODP, 5, 1536, 6645ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 6745ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 6845ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 6945ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 7045ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 7145ae9d61Sreyk "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 7245ae9d61Sreyk "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 7345ae9d61Sreyk "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 7445ae9d61Sreyk "02" 7545ae9d61Sreyk }, 7645ae9d61Sreyk { GROUP_MODP, 14, 2048, 7745ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 7845ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 7945ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 8045ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 8145ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 8245ae9d61Sreyk "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 8345ae9d61Sreyk "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 8445ae9d61Sreyk "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 8545ae9d61Sreyk "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 8645ae9d61Sreyk "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 8745ae9d61Sreyk "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 8845ae9d61Sreyk "02" 8945ae9d61Sreyk }, 9045ae9d61Sreyk { GROUP_MODP, 15, 3072, 9145ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 9245ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 9345ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 9445ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 9545ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 9645ae9d61Sreyk "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 9745ae9d61Sreyk "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 9845ae9d61Sreyk "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 9945ae9d61Sreyk "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 10045ae9d61Sreyk "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 10145ae9d61Sreyk "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 10245ae9d61Sreyk "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 10345ae9d61Sreyk "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 10445ae9d61Sreyk "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 10545ae9d61Sreyk "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 10645ae9d61Sreyk "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", 10745ae9d61Sreyk "02" 10845ae9d61Sreyk }, 10945ae9d61Sreyk { GROUP_MODP, 16, 4096, 11045ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 11145ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 11245ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 11345ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 11445ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 11545ae9d61Sreyk "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 11645ae9d61Sreyk "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 11745ae9d61Sreyk "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 11845ae9d61Sreyk "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 11945ae9d61Sreyk "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 12045ae9d61Sreyk "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 12145ae9d61Sreyk "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 12245ae9d61Sreyk "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 12345ae9d61Sreyk "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 12445ae9d61Sreyk "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 12545ae9d61Sreyk "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 12645ae9d61Sreyk "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 12745ae9d61Sreyk "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 12845ae9d61Sreyk "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 12945ae9d61Sreyk "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 13045ae9d61Sreyk "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" 13145ae9d61Sreyk "FFFFFFFFFFFFFFFF", 13245ae9d61Sreyk "02" 13345ae9d61Sreyk }, 13445ae9d61Sreyk { GROUP_MODP, 17, 6144, 13545ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 13645ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 13745ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 13845ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 13945ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 14045ae9d61Sreyk "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 14145ae9d61Sreyk "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 14245ae9d61Sreyk "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 14345ae9d61Sreyk "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 14445ae9d61Sreyk "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 14545ae9d61Sreyk "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 14645ae9d61Sreyk "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 14745ae9d61Sreyk "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 14845ae9d61Sreyk "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 14945ae9d61Sreyk "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 15045ae9d61Sreyk "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 15145ae9d61Sreyk "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 15245ae9d61Sreyk "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 15345ae9d61Sreyk "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 15445ae9d61Sreyk "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 15545ae9d61Sreyk "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" 15645ae9d61Sreyk "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" 15745ae9d61Sreyk "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" 15845ae9d61Sreyk "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" 15945ae9d61Sreyk "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" 16045ae9d61Sreyk "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" 16145ae9d61Sreyk "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" 16245ae9d61Sreyk "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" 16345ae9d61Sreyk "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" 16445ae9d61Sreyk "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" 16545ae9d61Sreyk "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" 16645ae9d61Sreyk "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", 16745ae9d61Sreyk "02" 16845ae9d61Sreyk }, 16945ae9d61Sreyk { GROUP_MODP, 18, 8192, 17045ae9d61Sreyk "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 17145ae9d61Sreyk "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 17245ae9d61Sreyk "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 17345ae9d61Sreyk "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 17445ae9d61Sreyk "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 17545ae9d61Sreyk "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 17645ae9d61Sreyk "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 17745ae9d61Sreyk "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 17845ae9d61Sreyk "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 17945ae9d61Sreyk "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 18045ae9d61Sreyk "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 18145ae9d61Sreyk "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 18245ae9d61Sreyk "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 18345ae9d61Sreyk "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 18445ae9d61Sreyk "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 18545ae9d61Sreyk "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 18645ae9d61Sreyk "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 18745ae9d61Sreyk "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 18845ae9d61Sreyk "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 18945ae9d61Sreyk "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 19045ae9d61Sreyk "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" 19145ae9d61Sreyk "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" 19245ae9d61Sreyk "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" 19345ae9d61Sreyk "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" 19445ae9d61Sreyk "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" 19545ae9d61Sreyk "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" 19645ae9d61Sreyk "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" 19745ae9d61Sreyk "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" 19845ae9d61Sreyk "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" 19945ae9d61Sreyk "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" 20045ae9d61Sreyk "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" 20145ae9d61Sreyk "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" 20245ae9d61Sreyk "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" 20345ae9d61Sreyk "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" 20445ae9d61Sreyk "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" 20545ae9d61Sreyk "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" 20645ae9d61Sreyk "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" 20745ae9d61Sreyk "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" 20845ae9d61Sreyk "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" 20945ae9d61Sreyk "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" 21045ae9d61Sreyk "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" 21145ae9d61Sreyk "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" 21245ae9d61Sreyk "60C980DD98EDD3DFFFFFFFFFFFFFFFFF", 21345ae9d61Sreyk "02" 21445ae9d61Sreyk }, 215369beec1Sreyk { GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 }, 216369beec1Sreyk { GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 }, 217369beec1Sreyk { GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 }, 21845ae9d61Sreyk { GROUP_MODP, 22, 1024, 21945ae9d61Sreyk "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" 22045ae9d61Sreyk "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" 22145ae9d61Sreyk "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" 22245ae9d61Sreyk "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" 22345ae9d61Sreyk "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" 22445ae9d61Sreyk "DF1FB2BC2E4A4371", 22545ae9d61Sreyk "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" 22645ae9d61Sreyk "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" 22745ae9d61Sreyk "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" 22845ae9d61Sreyk "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" 22945ae9d61Sreyk "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" 23045ae9d61Sreyk "855E6EEB22B3B2E5" 23145ae9d61Sreyk }, 23245ae9d61Sreyk { GROUP_MODP, 23, 2048, 23345ae9d61Sreyk "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" 23445ae9d61Sreyk "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" 23545ae9d61Sreyk "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" 23645ae9d61Sreyk "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" 23745ae9d61Sreyk "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" 23845ae9d61Sreyk "B3BF8A317091883681286130BC8985DB1602E714415D9330" 23945ae9d61Sreyk "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" 24045ae9d61Sreyk "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" 24145ae9d61Sreyk "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" 24245ae9d61Sreyk "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" 24345ae9d61Sreyk "CF9DE5384E71B81C0AC4DFFE0C10E64F", 24445ae9d61Sreyk "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" 24545ae9d61Sreyk "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" 24645ae9d61Sreyk "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" 24745ae9d61Sreyk "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" 24845ae9d61Sreyk "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" 24945ae9d61Sreyk "F180EB34118E98D119529A45D6F834566E3025E316A330EF" 25045ae9d61Sreyk "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" 25145ae9d61Sreyk "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" 25245ae9d61Sreyk "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" 25345ae9d61Sreyk "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" 25445ae9d61Sreyk "81BC087F2A7065B384B890D3191F2BFA" 25545ae9d61Sreyk }, 25645ae9d61Sreyk { GROUP_MODP, 24, 2048, 25745ae9d61Sreyk "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" 25845ae9d61Sreyk "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" 25945ae9d61Sreyk "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" 26045ae9d61Sreyk "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" 26145ae9d61Sreyk "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" 26245ae9d61Sreyk "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" 26345ae9d61Sreyk "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" 26445ae9d61Sreyk "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" 26545ae9d61Sreyk "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" 26645ae9d61Sreyk "75F26375D7014103A4B54330C198AF126116D2276E11715F" 26745ae9d61Sreyk "693877FAD7EF09CADB094AE91E1A1597", 26845ae9d61Sreyk "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" 26945ae9d61Sreyk "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" 27045ae9d61Sreyk "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" 27145ae9d61Sreyk "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" 27245ae9d61Sreyk "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" 27345ae9d61Sreyk "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" 27445ae9d61Sreyk "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" 27545ae9d61Sreyk "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" 27645ae9d61Sreyk "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" 27745ae9d61Sreyk "184B523D1DB246C32F63078490F00EF8D647D148D4795451" 27845ae9d61Sreyk "5E2327CFEF98C582664B4C0F6CC41659" 27945ae9d61Sreyk }, 280369beec1Sreyk { GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 }, 281369beec1Sreyk { GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 } 28245ae9d61Sreyk }; 28345ae9d61Sreyk 28445ae9d61Sreyk void 28545ae9d61Sreyk group_init(void) 28645ae9d61Sreyk { 2870d5bf58dSreyk /* currently not used */ 28845ae9d61Sreyk return; 28945ae9d61Sreyk } 29045ae9d61Sreyk 29145ae9d61Sreyk void 29245ae9d61Sreyk group_free(struct group *group) 29345ae9d61Sreyk { 29445ae9d61Sreyk if (group == NULL) 29545ae9d61Sreyk return; 29645ae9d61Sreyk if (group->dh != NULL) 29745ae9d61Sreyk DH_free(group->dh); 29845ae9d61Sreyk if (group->ec != NULL) 29945ae9d61Sreyk EC_KEY_free(group->ec); 30045ae9d61Sreyk group->spec = NULL; 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); 384*7d7b0856Sreyk 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 int codes; 40545ae9d61Sreyk DH *dh = group->dh; 40645ae9d61Sreyk 40745ae9d61Sreyk if (!DH_generate_key(dh)) 40845ae9d61Sreyk return (-1); 40945ae9d61Sreyk if (!DH_check(dh, &codes)) 41045ae9d61Sreyk return (-1); 41145ae9d61Sreyk if (!BN_bn2bin(dh->pub_key, buf)) 41245ae9d61Sreyk return (-1); 41345ae9d61Sreyk 414*7d7b0856Sreyk return (0); 41545ae9d61Sreyk } 41645ae9d61Sreyk 41745ae9d61Sreyk int 41845ae9d61Sreyk modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 41945ae9d61Sreyk { 42045ae9d61Sreyk BIGNUM *ex; 421*7d7b0856Sreyk int ret; 42245ae9d61Sreyk 42345ae9d61Sreyk if ((ex = BN_bin2bn(exchange, dh_getlen(group), NULL)) == NULL) 42445ae9d61Sreyk return (-1); 425*7d7b0856Sreyk 426*7d7b0856Sreyk ret = DH_compute_key(secret, ex, group->dh); 427*7d7b0856Sreyk BN_clear_free(ex); 428*7d7b0856Sreyk if (!ret) 42945ae9d61Sreyk return (-1); 43045ae9d61Sreyk 431*7d7b0856Sreyk return (0); 43245ae9d61Sreyk } 43345ae9d61Sreyk 43445ae9d61Sreyk int 43545ae9d61Sreyk ec_init(struct group *group) 43645ae9d61Sreyk { 43745ae9d61Sreyk if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL) 43845ae9d61Sreyk return (-1); 43945ae9d61Sreyk if (!EC_KEY_generate_key(group->ec)) 44045ae9d61Sreyk return (-1); 44145ae9d61Sreyk return (0); 44245ae9d61Sreyk } 44345ae9d61Sreyk 44445ae9d61Sreyk int 44545ae9d61Sreyk ec_getlen(struct group *group) 44645ae9d61Sreyk { 44745ae9d61Sreyk if (group->spec == NULL) 44845ae9d61Sreyk return (0); 44945ae9d61Sreyk return ((roundup(group->spec->bits, 8) * 2) / 8); 45045ae9d61Sreyk } 45145ae9d61Sreyk 45245ae9d61Sreyk int 45345ae9d61Sreyk ec_create_exchange(struct group *group, u_int8_t *buf) 45445ae9d61Sreyk { 4550d5bf58dSreyk size_t len; 4560d5bf58dSreyk 4570d5bf58dSreyk len = ec_getlen(group); 4580d5bf58dSreyk bzero(buf, len); 4590d5bf58dSreyk 46045ae9d61Sreyk return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 4610d5bf58dSreyk buf, len)); 46245ae9d61Sreyk } 46345ae9d61Sreyk 46445ae9d61Sreyk int 46545ae9d61Sreyk ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 46645ae9d61Sreyk { 46745ae9d61Sreyk const EC_GROUP *ecgroup = NULL; 46845ae9d61Sreyk const BIGNUM *privkey; 46945ae9d61Sreyk EC_POINT *exchangep = NULL, *secretp = NULL; 47045ae9d61Sreyk int ret = -1; 47145ae9d61Sreyk 47245ae9d61Sreyk if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 47345ae9d61Sreyk (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 47445ae9d61Sreyk goto done; 47545ae9d61Sreyk 47645ae9d61Sreyk if ((exchangep = 47745ae9d61Sreyk ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 47845ae9d61Sreyk goto done; 47945ae9d61Sreyk 48045ae9d61Sreyk if ((secretp = EC_POINT_new(ecgroup)) == NULL) 48145ae9d61Sreyk goto done; 48245ae9d61Sreyk 48345ae9d61Sreyk if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 48445ae9d61Sreyk goto done; 48545ae9d61Sreyk 48645ae9d61Sreyk ret = ec_point2raw(group, secretp, secret, ec_getlen(group)); 48745ae9d61Sreyk 48845ae9d61Sreyk done: 48945ae9d61Sreyk if (exchangep != NULL) 49045ae9d61Sreyk EC_POINT_clear_free(exchangep); 49145ae9d61Sreyk if (secretp != NULL) 49245ae9d61Sreyk EC_POINT_clear_free(secretp); 49345ae9d61Sreyk 49445ae9d61Sreyk return (ret); 49545ae9d61Sreyk } 49645ae9d61Sreyk 49745ae9d61Sreyk int 49845ae9d61Sreyk ec_point2raw(struct group *group, const EC_POINT *point, 49945ae9d61Sreyk u_int8_t *buf, size_t len) 50045ae9d61Sreyk { 50145ae9d61Sreyk const EC_GROUP *ecgroup = NULL; 50245ae9d61Sreyk BN_CTX *bnctx = NULL; 50345ae9d61Sreyk BIGNUM *x = NULL, *y = NULL; 50445ae9d61Sreyk int ret = -1; 50545ae9d61Sreyk size_t xlen, ylen; 50645ae9d61Sreyk off_t xoff, yoff; 50745ae9d61Sreyk 50845ae9d61Sreyk if ((bnctx = BN_CTX_new()) == NULL) 50945ae9d61Sreyk goto done; 51045ae9d61Sreyk BN_CTX_start(bnctx); 51145ae9d61Sreyk if ((x = BN_CTX_get(bnctx)) == NULL || 51245ae9d61Sreyk (y = BN_CTX_get(bnctx)) == NULL) 51345ae9d61Sreyk goto done; 51445ae9d61Sreyk 51545ae9d61Sreyk if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 51645ae9d61Sreyk goto done; 51745ae9d61Sreyk 51845ae9d61Sreyk if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 51945ae9d61Sreyk NID_X9_62_prime_field) { 52045ae9d61Sreyk if (!EC_POINT_get_affine_coordinates_GFp(ecgroup, 52145ae9d61Sreyk point, x, y, bnctx)) 52245ae9d61Sreyk goto done; 52345ae9d61Sreyk } else { 52445ae9d61Sreyk if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup, 52545ae9d61Sreyk point, x, y, bnctx)) 52645ae9d61Sreyk goto done; 52745ae9d61Sreyk } 52845ae9d61Sreyk 52945ae9d61Sreyk xlen = roundup(BN_num_bytes(x), 2); 53045ae9d61Sreyk xoff = xlen - BN_num_bytes(x); 53145ae9d61Sreyk if (!BN_bn2bin(x, buf + xoff)) 53245ae9d61Sreyk goto done; 53345ae9d61Sreyk 53445ae9d61Sreyk ylen = roundup(BN_num_bytes(y), 2); 53545ae9d61Sreyk yoff = (ylen - BN_num_bytes(y)) + xlen; 53645ae9d61Sreyk if (!BN_bn2bin(y, buf + yoff)) 53745ae9d61Sreyk goto done; 53845ae9d61Sreyk 53945ae9d61Sreyk ret = 0; 54045ae9d61Sreyk done: 54145ae9d61Sreyk BN_CTX_end(bnctx); 54245ae9d61Sreyk BN_CTX_free(bnctx); 54345ae9d61Sreyk 54445ae9d61Sreyk return (ret); 54545ae9d61Sreyk } 54645ae9d61Sreyk 54745ae9d61Sreyk EC_POINT * 54845ae9d61Sreyk ec_raw2point(struct group *group, u_int8_t *buf, size_t len) 54945ae9d61Sreyk { 55045ae9d61Sreyk const EC_GROUP *ecgroup = NULL; 55145ae9d61Sreyk EC_POINT *point = NULL; 55245ae9d61Sreyk BN_CTX *bnctx = NULL; 55345ae9d61Sreyk BIGNUM *x = NULL, *y = NULL; 55445ae9d61Sreyk int ret = -1; 55545ae9d61Sreyk size_t eclen; 55645ae9d61Sreyk size_t xlen, ylen; 55745ae9d61Sreyk 55845ae9d61Sreyk if ((bnctx = BN_CTX_new()) == NULL) 55945ae9d61Sreyk goto done; 56045ae9d61Sreyk BN_CTX_start(bnctx); 56145ae9d61Sreyk if ((x = BN_CTX_get(bnctx)) == NULL || 56245ae9d61Sreyk (y = BN_CTX_get(bnctx)) == NULL) 56345ae9d61Sreyk goto done; 56445ae9d61Sreyk 56545ae9d61Sreyk eclen = ec_getlen(group); 56645ae9d61Sreyk if (len < eclen) 56745ae9d61Sreyk goto done; 56845ae9d61Sreyk xlen = ylen = eclen / 2; 56945ae9d61Sreyk if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 57045ae9d61Sreyk (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 57145ae9d61Sreyk goto done; 57245ae9d61Sreyk 57345ae9d61Sreyk if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 57445ae9d61Sreyk goto done; 57545ae9d61Sreyk 57645ae9d61Sreyk if ((point = EC_POINT_new(ecgroup)) == NULL) 57745ae9d61Sreyk goto done; 57845ae9d61Sreyk 57945ae9d61Sreyk if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 58045ae9d61Sreyk NID_X9_62_prime_field) { 58145ae9d61Sreyk if (!EC_POINT_set_affine_coordinates_GFp(ecgroup, 58245ae9d61Sreyk point, x, y, bnctx)) 58345ae9d61Sreyk goto done; 58445ae9d61Sreyk } else { 58545ae9d61Sreyk if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup, 58645ae9d61Sreyk point, x, y, bnctx)) 58745ae9d61Sreyk goto done; 58845ae9d61Sreyk } 58945ae9d61Sreyk 59045ae9d61Sreyk ret = 0; 59145ae9d61Sreyk done: 59245ae9d61Sreyk if (ret != 0 && point != NULL) 59345ae9d61Sreyk EC_POINT_clear_free(point); 59445ae9d61Sreyk BN_CTX_end(bnctx); 59545ae9d61Sreyk BN_CTX_free(bnctx); 59645ae9d61Sreyk 59745ae9d61Sreyk return (point); 59845ae9d61Sreyk } 599