1 /* $OpenBSD: dh.c,v 1.17 2015/08/21 11:59:27 reyk Exp $ */ 2 3 /* 4 * Copyright (c) 2010-2014 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> /* roundup */ 20 #include <string.h> 21 22 #include <openssl/obj_mac.h> 23 #include <openssl/dh.h> 24 #include <openssl/ec.h> 25 #include <openssl/ecdh.h> 26 #include <openssl/bn.h> 27 28 #include "dh.h" 29 30 int dh_init(struct group *); 31 32 /* MODP */ 33 int modp_init(struct group *); 34 int modp_getlen(struct group *); 35 int modp_create_exchange(struct group *, uint8_t *); 36 int modp_create_shared(struct group *, uint8_t *, uint8_t *); 37 38 /* EC2N/ECP */ 39 int ec_init(struct group *); 40 int ec_getlen(struct group *); 41 int ec_create_exchange(struct group *, uint8_t *); 42 int ec_create_shared(struct group *, uint8_t *, uint8_t *); 43 44 int ec_point2raw(struct group *, const EC_POINT *, uint8_t *, size_t); 45 EC_POINT * 46 ec_raw2point(struct group *, uint8_t *, size_t); 47 48 /* curve25519 */ 49 int ec25519_init(struct group *); 50 int ec25519_getlen(struct group *); 51 int ec25519_create_exchange(struct group *, uint8_t *); 52 int ec25519_create_shared(struct group *, uint8_t *, uint8_t *); 53 54 #define CURVE25519_SIZE 32 /* 256 bits */ 55 struct curve25519_key { 56 uint8_t secret[CURVE25519_SIZE]; 57 uint8_t public[CURVE25519_SIZE]; 58 }; 59 extern int crypto_scalarmult_curve25519(unsigned char a[CURVE25519_SIZE], 60 const unsigned char b[CURVE25519_SIZE], 61 const unsigned char c[CURVE25519_SIZE]) 62 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 63 __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))) 64 __attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE))); 65 66 struct group_id ike_groups[] = { 67 { GROUP_MODP, 1, 768, 68 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 69 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 70 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 71 "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 72 "02" 73 }, 74 { GROUP_MODP, 2, 1024, 75 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 76 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 77 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 78 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 79 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" 80 "FFFFFFFFFFFFFFFF", 81 "02" 82 }, 83 { GROUP_EC2N, 3, 155, NULL, NULL, NID_ipsec3 }, 84 { GROUP_EC2N, 4, 185, NULL, NULL, NID_ipsec4 }, 85 { GROUP_MODP, 5, 1536, 86 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 87 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 88 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 89 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 90 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 91 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 92 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 93 "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 94 "02" 95 }, 96 { GROUP_MODP, 14, 2048, 97 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 98 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 99 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 100 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 101 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 102 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 103 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 104 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 105 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 106 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 107 "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 108 "02" 109 }, 110 { GROUP_MODP, 15, 3072, 111 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 112 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 113 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 114 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 115 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 116 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 117 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 118 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 119 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 120 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 121 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 122 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 123 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 124 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 125 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 126 "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", 127 "02" 128 }, 129 { GROUP_MODP, 16, 4096, 130 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 131 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 132 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 133 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 134 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 135 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 136 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 137 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 138 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 139 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 140 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 141 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 142 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 143 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 144 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 145 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 146 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 147 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 148 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 149 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 150 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" 151 "FFFFFFFFFFFFFFFF", 152 "02" 153 }, 154 { GROUP_MODP, 17, 6144, 155 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 156 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 157 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 158 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 159 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 160 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 161 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 162 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 163 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 164 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 165 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 166 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 167 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 168 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 169 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 170 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 171 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 172 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 173 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 174 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 175 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" 176 "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" 177 "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" 178 "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" 179 "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" 180 "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" 181 "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" 182 "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" 183 "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" 184 "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" 185 "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" 186 "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", 187 "02" 188 }, 189 { GROUP_MODP, 18, 8192, 190 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 191 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 192 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 193 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 194 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 195 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 196 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 197 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 198 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 199 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 200 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 201 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 202 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 203 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 204 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 205 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 206 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 207 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 208 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 209 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 210 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" 211 "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" 212 "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" 213 "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" 214 "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" 215 "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" 216 "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" 217 "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" 218 "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" 219 "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" 220 "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" 221 "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" 222 "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" 223 "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" 224 "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" 225 "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" 226 "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" 227 "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" 228 "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" 229 "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" 230 "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" 231 "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" 232 "60C980DD98EDD3DFFFFFFFFFFFFFFFFF", 233 "02" 234 }, 235 { GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 }, 236 { GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 }, 237 { GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 }, 238 { GROUP_MODP, 22, 1024, 239 "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" 240 "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" 241 "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" 242 "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" 243 "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" 244 "DF1FB2BC2E4A4371", 245 "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" 246 "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" 247 "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" 248 "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" 249 "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" 250 "855E6EEB22B3B2E5" 251 }, 252 { GROUP_MODP, 23, 2048, 253 "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" 254 "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" 255 "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" 256 "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" 257 "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" 258 "B3BF8A317091883681286130BC8985DB1602E714415D9330" 259 "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" 260 "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" 261 "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" 262 "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" 263 "CF9DE5384E71B81C0AC4DFFE0C10E64F", 264 "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" 265 "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" 266 "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" 267 "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" 268 "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" 269 "F180EB34118E98D119529A45D6F834566E3025E316A330EF" 270 "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" 271 "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" 272 "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" 273 "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" 274 "81BC087F2A7065B384B890D3191F2BFA" 275 }, 276 { GROUP_MODP, 24, 2048, 277 "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" 278 "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30" 279 "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD" 280 "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B" 281 "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C" 282 "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E" 283 "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9" 284 "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026" 285 "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3" 286 "75F26375D7014103A4B54330C198AF126116D2276E11715F" 287 "693877FAD7EF09CADB094AE91E1A1597", 288 "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054" 289 "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555" 290 "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18" 291 "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B" 292 "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83" 293 "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55" 294 "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14" 295 "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915" 296 "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6" 297 "184B523D1DB246C32F63078490F00EF8D647D148D4795451" 298 "5E2327CFEF98C582664B4C0F6CC41659" 299 }, 300 { GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 }, 301 { GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 }, 302 { GROUP_ECP, 27, 224, NULL, NULL, NID_brainpoolP224r1 }, 303 { GROUP_ECP, 28, 256, NULL, NULL, NID_brainpoolP256r1 }, 304 { GROUP_ECP, 29, 384, NULL, NULL, NID_brainpoolP384r1 }, 305 { GROUP_ECP, 30, 512, NULL, NULL, NID_brainpoolP512r1 }, 306 307 /* "Private use" extensions */ 308 { GROUP_CURVE25519, 1034, CURVE25519_SIZE * 8 } 309 }; 310 311 void 312 group_init(void) 313 { 314 /* currently not used */ 315 return; 316 } 317 318 void 319 group_free(struct group *group) 320 { 321 if (group == NULL) 322 return; 323 if (group->dh != NULL) 324 DH_free(group->dh); 325 if (group->ec != NULL) 326 EC_KEY_free(group->ec); 327 if (group->curve25519 != NULL) { 328 explicit_bzero(group->curve25519, 329 sizeof(struct curve25519_key)); 330 free(group->curve25519); 331 } 332 group->spec = NULL; 333 free(group); 334 } 335 336 struct group * 337 group_get(uint32_t id) 338 { 339 struct group_id *p = NULL; 340 struct group *group; 341 unsigned int i, items; 342 343 items = sizeof(ike_groups) / sizeof(ike_groups[0]); 344 for (i = 0; i < items; i++) { 345 if (id == ike_groups[i].id) { 346 p = &ike_groups[i]; 347 break; 348 } 349 } 350 if (p == NULL) 351 return (NULL); 352 353 if ((group = calloc(1, sizeof(*group))) == NULL) 354 return (NULL); 355 356 group->id = id; 357 group->spec = p; 358 359 switch (p->type) { 360 case GROUP_MODP: 361 group->init = modp_init; 362 group->getlen = modp_getlen; 363 group->exchange = modp_create_exchange; 364 group->shared = modp_create_shared; 365 break; 366 case GROUP_EC2N: 367 case GROUP_ECP: 368 group->init = ec_init; 369 group->getlen = ec_getlen; 370 group->exchange = ec_create_exchange; 371 group->shared = ec_create_shared; 372 break; 373 case GROUP_CURVE25519: 374 group->init = ec25519_init; 375 group->getlen = ec25519_getlen; 376 group->exchange = ec25519_create_exchange; 377 group->shared = ec25519_create_shared; 378 break; 379 default: 380 group_free(group); 381 return (NULL); 382 } 383 384 if (dh_init(group) != 0) { 385 group_free(group); 386 return (NULL); 387 } 388 389 return (group); 390 } 391 392 int 393 dh_init(struct group *group) 394 { 395 return (group->init(group)); 396 } 397 398 int 399 dh_getlen(struct group *group) 400 { 401 return (group->getlen(group)); 402 } 403 404 int 405 dh_create_exchange(struct group *group, uint8_t *buf) 406 { 407 return (group->exchange(group, buf)); 408 } 409 410 int 411 dh_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange) 412 { 413 return (group->shared(group, secret, exchange)); 414 } 415 416 int 417 modp_init(struct group *group) 418 { 419 DH *dh; 420 421 if ((dh = DH_new()) == NULL) 422 return (-1); 423 group->dh = dh; 424 425 if (!BN_hex2bn(&dh->p, group->spec->prime) || 426 !BN_hex2bn(&dh->g, group->spec->generator)) 427 return (-1); 428 429 return (0); 430 } 431 432 int 433 modp_getlen(struct group *group) 434 { 435 if (group->spec == NULL) 436 return (0); 437 return (roundup(group->spec->bits, 8) / 8); 438 } 439 440 int 441 modp_create_exchange(struct group *group, uint8_t *buf) 442 { 443 DH *dh = group->dh; 444 int len, ret; 445 446 if (!DH_generate_key(dh)) 447 return (-1); 448 ret = BN_bn2bin(dh->pub_key, buf); 449 if (!ret) 450 return (-1); 451 452 len = dh_getlen(group); 453 454 /* add zero padding */ 455 if (ret < len) { 456 bcopy(buf, buf + (len - ret), ret); 457 bzero(buf, len - ret); 458 } 459 460 return (0); 461 } 462 463 int 464 modp_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange) 465 { 466 BIGNUM *ex; 467 int len, ret; 468 469 len = dh_getlen(group); 470 471 if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL) 472 return (-1); 473 474 ret = DH_compute_key(secret, ex, group->dh); 475 BN_clear_free(ex); 476 if (ret <= 0) 477 return (-1); 478 479 /* add zero padding */ 480 if (ret < len) { 481 bcopy(secret, secret + (len - ret), ret); 482 bzero(secret, len - ret); 483 } 484 485 return (0); 486 } 487 488 int 489 ec_init(struct group *group) 490 { 491 if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL) 492 return (-1); 493 if (!EC_KEY_generate_key(group->ec)) 494 return (-1); 495 if (!EC_KEY_check_key(group->ec)) { 496 EC_KEY_free(group->ec); 497 return (-1); 498 } 499 return (0); 500 } 501 502 int 503 ec_getlen(struct group *group) 504 { 505 if (group->spec == NULL) 506 return (0); 507 /* NB: Return value will always be even */ 508 return ((roundup(group->spec->bits, 8) * 2) / 8); 509 } 510 511 int 512 ec_create_exchange(struct group *group, uint8_t *buf) 513 { 514 size_t len; 515 516 len = ec_getlen(group); 517 bzero(buf, len); 518 519 return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 520 buf, len)); 521 } 522 523 int 524 ec_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange) 525 { 526 const EC_GROUP *ecgroup = NULL; 527 const BIGNUM *privkey; 528 EC_KEY *exkey = NULL; 529 EC_POINT *exchangep = NULL, *secretp = NULL; 530 int ret = -1; 531 532 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 533 (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 534 goto done; 535 536 if ((exchangep = 537 ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 538 goto done; 539 540 if ((exkey = EC_KEY_new()) == NULL) 541 goto done; 542 if (!EC_KEY_set_group(exkey, ecgroup)) 543 goto done; 544 if (!EC_KEY_set_public_key(exkey, exchangep)) 545 goto done; 546 547 /* validate exchangep */ 548 if (!EC_KEY_check_key(exkey)) 549 goto done; 550 551 if ((secretp = EC_POINT_new(ecgroup)) == NULL) 552 goto done; 553 554 if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 555 goto done; 556 557 ret = ec_point2raw(group, secretp, secret, ec_getlen(group)); 558 559 done: 560 if (exkey != NULL) 561 EC_KEY_free(exkey); 562 if (exchangep != NULL) 563 EC_POINT_clear_free(exchangep); 564 if (secretp != NULL) 565 EC_POINT_clear_free(secretp); 566 567 return (ret); 568 } 569 570 int 571 ec_point2raw(struct group *group, const EC_POINT *point, 572 uint8_t *buf, size_t len) 573 { 574 const EC_GROUP *ecgroup = NULL; 575 BN_CTX *bnctx = NULL; 576 BIGNUM *x = NULL, *y = NULL; 577 int ret = -1; 578 size_t eclen, xlen, ylen; 579 off_t xoff, yoff; 580 581 if ((bnctx = BN_CTX_new()) == NULL) 582 goto done; 583 BN_CTX_start(bnctx); 584 if ((x = BN_CTX_get(bnctx)) == NULL || 585 (y = BN_CTX_get(bnctx)) == NULL) 586 goto done; 587 588 eclen = ec_getlen(group); 589 if (len < eclen) 590 goto done; 591 xlen = ylen = eclen / 2; 592 593 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 594 goto done; 595 596 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 597 NID_X9_62_prime_field) { 598 if (!EC_POINT_get_affine_coordinates_GFp(ecgroup, 599 point, x, y, bnctx)) 600 goto done; 601 } else { 602 if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup, 603 point, x, y, bnctx)) 604 goto done; 605 } 606 607 xoff = xlen - BN_num_bytes(x); 608 bzero(buf, xoff); 609 if (!BN_bn2bin(x, buf + xoff)) 610 goto done; 611 612 yoff = (ylen - BN_num_bytes(y)) + xlen; 613 bzero(buf + xlen, yoff - xlen); 614 if (!BN_bn2bin(y, buf + yoff)) 615 goto done; 616 617 ret = 0; 618 done: 619 /* Make sure to erase sensitive data */ 620 if (x != NULL) 621 BN_clear(x); 622 if (y != NULL) 623 BN_clear(y); 624 BN_CTX_end(bnctx); 625 BN_CTX_free(bnctx); 626 627 return (ret); 628 } 629 630 EC_POINT * 631 ec_raw2point(struct group *group, uint8_t *buf, size_t len) 632 { 633 const EC_GROUP *ecgroup = NULL; 634 EC_POINT *point = NULL; 635 BN_CTX *bnctx = NULL; 636 BIGNUM *x = NULL, *y = NULL; 637 int ret = -1; 638 size_t eclen; 639 size_t xlen, ylen; 640 641 if ((bnctx = BN_CTX_new()) == NULL) 642 goto done; 643 BN_CTX_start(bnctx); 644 if ((x = BN_CTX_get(bnctx)) == NULL || 645 (y = BN_CTX_get(bnctx)) == NULL) 646 goto done; 647 648 eclen = ec_getlen(group); 649 if (len < eclen) 650 goto done; 651 xlen = ylen = eclen / 2; 652 if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 653 (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 654 goto done; 655 656 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 657 goto done; 658 659 if ((point = EC_POINT_new(ecgroup)) == NULL) 660 goto done; 661 662 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 663 NID_X9_62_prime_field) { 664 if (!EC_POINT_set_affine_coordinates_GFp(ecgroup, 665 point, x, y, bnctx)) 666 goto done; 667 } else { 668 if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup, 669 point, x, y, bnctx)) 670 goto done; 671 } 672 673 ret = 0; 674 done: 675 if (ret != 0 && point != NULL) 676 EC_POINT_clear_free(point); 677 /* Make sure to erase sensitive data */ 678 if (x != NULL) 679 BN_clear(x); 680 if (y != NULL) 681 BN_clear(y); 682 BN_CTX_end(bnctx); 683 BN_CTX_free(bnctx); 684 685 return (point); 686 } 687 688 int 689 ec25519_init(struct group *group) 690 { 691 static const uint8_t basepoint[CURVE25519_SIZE] = { 9 }; 692 struct curve25519_key *curve25519; 693 694 if ((curve25519 = calloc(1, sizeof(*curve25519))) == NULL) 695 return (-1); 696 697 group->curve25519 = curve25519; 698 699 arc4random_buf(curve25519->secret, CURVE25519_SIZE); 700 crypto_scalarmult_curve25519(curve25519->public, 701 curve25519->secret, basepoint); 702 703 return (0); 704 } 705 706 int 707 ec25519_getlen(struct group *group) 708 { 709 if (group->spec == NULL) 710 return (0); 711 return (CURVE25519_SIZE); 712 } 713 714 int 715 ec25519_create_exchange(struct group *group, uint8_t *buf) 716 { 717 struct curve25519_key *curve25519 = group->curve25519; 718 719 memcpy(buf, curve25519->public, ec25519_getlen(group)); 720 return (0); 721 } 722 723 int 724 ec25519_create_shared(struct group *group, uint8_t *shared, uint8_t *public) 725 { 726 struct curve25519_key *curve25519 = group->curve25519; 727 728 crypto_scalarmult_curve25519(shared, curve25519->secret, public); 729 return (0); 730 } 731