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