diff options
Diffstat (limited to 'src/lib/libssl/tls_key_share.c')
| -rw-r--r-- | src/lib/libssl/tls_key_share.c | 157 |
1 files changed, 125 insertions, 32 deletions
diff --git a/src/lib/libssl/tls_key_share.c b/src/lib/libssl/tls_key_share.c index 1bce651e10..6e390f4a24 100644 --- a/src/lib/libssl/tls_key_share.c +++ b/src/lib/libssl/tls_key_share.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls_key_share.c,v 1.1 2022/01/05 17:10:03 jsing Exp $ */ | 1 | /* $OpenBSD: tls_key_share.c,v 1.2 2022/01/06 18:23:56 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -28,6 +28,9 @@ struct tls_key_share { | |||
| 28 | int nid; | 28 | int nid; |
| 29 | uint16_t group_id; | 29 | uint16_t group_id; |
| 30 | 30 | ||
| 31 | DH *dhe; | ||
| 32 | DH *dhe_peer; | ||
| 33 | |||
| 31 | EC_KEY *ecdhe; | 34 | EC_KEY *ecdhe; |
| 32 | EC_KEY *ecdhe_peer; | 35 | EC_KEY *ecdhe_peer; |
| 33 | 36 | ||
| @@ -36,14 +39,10 @@ struct tls_key_share { | |||
| 36 | uint8_t *x25519_peer_public; | 39 | uint8_t *x25519_peer_public; |
| 37 | }; | 40 | }; |
| 38 | 41 | ||
| 39 | struct tls_key_share * | 42 | static struct tls_key_share * |
| 40 | tls_key_share_new(uint16_t group_id) | 43 | tls_key_share_new_internal(int nid, uint16_t group_id) |
| 41 | { | 44 | { |
| 42 | struct tls_key_share *ks; | 45 | struct tls_key_share *ks; |
| 43 | int nid; | ||
| 44 | |||
| 45 | if ((nid = tls1_ec_curve_id2nid(group_id)) == 0) | ||
| 46 | return NULL; | ||
| 47 | 46 | ||
| 48 | if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL) | 47 | if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL) |
| 49 | return NULL; | 48 | return NULL; |
| @@ -55,14 +54,27 @@ tls_key_share_new(uint16_t group_id) | |||
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | struct tls_key_share * | 56 | struct tls_key_share * |
| 58 | tls_key_share_new_nid(int nid) | 57 | tls_key_share_new(uint16_t group_id) |
| 59 | { | 58 | { |
| 60 | uint16_t group_id; | 59 | int nid; |
| 61 | 60 | ||
| 62 | if ((group_id = tls1_ec_nid2curve_id(nid)) == 0) | 61 | if ((nid = tls1_ec_curve_id2nid(group_id)) == 0) |
| 63 | return NULL; | 62 | return NULL; |
| 64 | 63 | ||
| 65 | return tls_key_share_new(group_id); | 64 | return tls_key_share_new_internal(nid, group_id); |
| 65 | } | ||
| 66 | |||
| 67 | struct tls_key_share * | ||
| 68 | tls_key_share_new_nid(int nid) | ||
| 69 | { | ||
| 70 | uint16_t group_id = 0; | ||
| 71 | |||
| 72 | if (nid != NID_dhKeyAgreement) { | ||
| 73 | if ((group_id = tls1_ec_nid2curve_id(nid)) == 0) | ||
| 74 | return NULL; | ||
| 75 | } | ||
| 76 | |||
| 77 | return tls_key_share_new_internal(nid, group_id); | ||
| 66 | } | 78 | } |
| 67 | 79 | ||
| 68 | void | 80 | void |
| @@ -71,6 +83,9 @@ tls_key_share_free(struct tls_key_share *ks) | |||
| 71 | if (ks == NULL) | 83 | if (ks == NULL) |
| 72 | return; | 84 | return; |
| 73 | 85 | ||
| 86 | DH_free(ks->dhe); | ||
| 87 | DH_free(ks->dhe_peer); | ||
| 88 | |||
| 74 | EC_KEY_free(ks->ecdhe); | 89 | EC_KEY_free(ks->ecdhe); |
| 75 | EC_KEY_free(ks->ecdhe_peer); | 90 | EC_KEY_free(ks->ecdhe_peer); |
| 76 | 91 | ||
| @@ -88,19 +103,33 @@ tls_key_share_group(struct tls_key_share *ks) | |||
| 88 | } | 103 | } |
| 89 | 104 | ||
| 90 | int | 105 | int |
| 106 | tls_key_share_nid(struct tls_key_share *ks) | ||
| 107 | { | ||
| 108 | return ks->nid; | ||
| 109 | } | ||
| 110 | |||
| 111 | int | ||
| 91 | tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey) | 112 | tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey) |
| 92 | { | 113 | { |
| 93 | if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) { | 114 | if (ks->nid == NID_dhKeyAgreement && ks->dhe_peer != NULL) |
| 94 | if (!ssl_kex_dummy_ecdhe_x25519(pkey)) | 115 | return EVP_PKEY_set1_DH(pkey, ks->dhe_peer); |
| 95 | return 0; | 116 | |
| 96 | } else if (ks->ecdhe_peer != NULL) { | 117 | if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) |
| 97 | if (!EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer)) | 118 | return ssl_kex_dummy_ecdhe_x25519(pkey); |
| 98 | return 0; | 119 | |
| 99 | } else { | 120 | if (ks->ecdhe_peer != NULL) |
| 121 | return EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer); | ||
| 122 | |||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static int | ||
| 127 | tls_key_share_generate_dhe(struct tls_key_share *ks) | ||
| 128 | { | ||
| 129 | if (ks->dhe == NULL) | ||
| 100 | return 0; | 130 | return 0; |
| 101 | } | ||
| 102 | 131 | ||
| 103 | return 1; | 132 | return ssl_kex_generate_dhe(ks->dhe, ks->dhe); |
| 104 | } | 133 | } |
| 105 | 134 | ||
| 106 | static int | 135 | static int |
| @@ -161,6 +190,9 @@ tls_key_share_generate_x25519(struct tls_key_share *ks) | |||
| 161 | int | 190 | int |
| 162 | tls_key_share_generate(struct tls_key_share *ks) | 191 | tls_key_share_generate(struct tls_key_share *ks) |
| 163 | { | 192 | { |
| 193 | if (ks->nid == NID_dhKeyAgreement) | ||
| 194 | return tls_key_share_generate_dhe(ks); | ||
| 195 | |||
| 164 | if (ks->nid == NID_X25519) | 196 | if (ks->nid == NID_X25519) |
| 165 | return tls_key_share_generate_x25519(ks); | 197 | return tls_key_share_generate_x25519(ks); |
| 166 | 198 | ||
| @@ -168,6 +200,15 @@ tls_key_share_generate(struct tls_key_share *ks) | |||
| 168 | } | 200 | } |
| 169 | 201 | ||
| 170 | static int | 202 | static int |
| 203 | tls_key_share_public_dhe(struct tls_key_share *ks, CBB *cbb) | ||
| 204 | { | ||
| 205 | if (ks->dhe == NULL) | ||
| 206 | return 0; | ||
| 207 | |||
| 208 | return ssl_kex_public_dhe(ks->dhe, cbb); | ||
| 209 | } | ||
| 210 | |||
| 211 | static int | ||
| 171 | tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb) | 212 | tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb) |
| 172 | { | 213 | { |
| 173 | if (ks->ecdhe == NULL) | 214 | if (ks->ecdhe == NULL) |
| @@ -188,6 +229,9 @@ tls_key_share_public_x25519(struct tls_key_share *ks, CBB *cbb) | |||
| 188 | int | 229 | int |
| 189 | tls_key_share_public(struct tls_key_share *ks, CBB *cbb) | 230 | tls_key_share_public(struct tls_key_share *ks, CBB *cbb) |
| 190 | { | 231 | { |
| 232 | if (ks->nid == NID_dhKeyAgreement) | ||
| 233 | return tls_key_share_public_dhe(ks, cbb); | ||
| 234 | |||
| 191 | if (ks->nid == NID_X25519) | 235 | if (ks->nid == NID_X25519) |
| 192 | return tls_key_share_public_x25519(ks, cbb); | 236 | return tls_key_share_public_x25519(ks, cbb); |
| 193 | 237 | ||
| @@ -195,6 +239,43 @@ tls_key_share_public(struct tls_key_share *ks, CBB *cbb) | |||
| 195 | } | 239 | } |
| 196 | 240 | ||
| 197 | static int | 241 | static int |
| 242 | tls_key_share_peer_params_dhe(struct tls_key_share *ks, CBS *cbs, | ||
| 243 | int *invalid_params) | ||
| 244 | { | ||
| 245 | if (ks->dhe != NULL || ks->dhe_peer != NULL) | ||
| 246 | return 0; | ||
| 247 | |||
| 248 | if ((ks->dhe_peer = DH_new()) == NULL) | ||
| 249 | return 0; | ||
| 250 | if (!ssl_kex_peer_params_dhe(ks->dhe_peer, cbs, invalid_params)) | ||
| 251 | return 0; | ||
| 252 | if ((ks->dhe = DHparams_dup(ks->dhe_peer)) == NULL) | ||
| 253 | return 0; | ||
| 254 | |||
| 255 | return 1; | ||
| 256 | } | ||
| 257 | |||
| 258 | int | ||
| 259 | tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs, | ||
| 260 | int *invalid_params) | ||
| 261 | { | ||
| 262 | if (ks->nid != NID_dhKeyAgreement) | ||
| 263 | return 0; | ||
| 264 | |||
| 265 | return tls_key_share_peer_params_dhe(ks, cbs, invalid_params); | ||
| 266 | } | ||
| 267 | |||
| 268 | static int | ||
| 269 | tls_key_share_peer_public_dhe(struct tls_key_share *ks, CBS *cbs, | ||
| 270 | int *invalid_key) | ||
| 271 | { | ||
| 272 | if (ks->dhe_peer == NULL) | ||
| 273 | return 0; | ||
| 274 | |||
| 275 | return ssl_kex_peer_public_dhe(ks->dhe_peer, cbs, invalid_key); | ||
| 276 | } | ||
| 277 | |||
| 278 | static int | ||
| 198 | tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share *ks, CBS *cbs) | 279 | tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share *ks, CBS *cbs) |
| 199 | { | 280 | { |
| 200 | EC_KEY *ecdhe = NULL; | 281 | EC_KEY *ecdhe = NULL; |
| @@ -234,21 +315,29 @@ tls_key_share_peer_public_x25519(struct tls_key_share *ks, CBS *cbs) | |||
| 234 | } | 315 | } |
| 235 | 316 | ||
| 236 | int | 317 | int |
| 237 | tls_key_share_peer_public(struct tls_key_share *ks, uint16_t group, | 318 | tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs, int *invalid_key) |
| 238 | CBS *cbs) | ||
| 239 | { | 319 | { |
| 240 | if (ks->group_id != group) | 320 | if (invalid_key != NULL) |
| 241 | return 0; | 321 | *invalid_key = 0; |
| 242 | 322 | ||
| 243 | if (ks->nid == NID_X25519) { | 323 | if (ks->nid == NID_dhKeyAgreement) |
| 244 | if (!tls_key_share_peer_public_x25519(ks, cbs)) | 324 | return tls_key_share_peer_public_dhe(ks, cbs, invalid_key); |
| 245 | return 0; | ||
| 246 | } else { | ||
| 247 | if (!tls_key_share_peer_public_ecdhe_ecp(ks, cbs)) | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | 325 | ||
| 251 | return 1; | 326 | if (ks->nid == NID_X25519) |
| 327 | return tls_key_share_peer_public_x25519(ks, cbs); | ||
| 328 | |||
| 329 | return tls_key_share_peer_public_ecdhe_ecp(ks, cbs); | ||
| 330 | } | ||
| 331 | |||
| 332 | static int | ||
| 333 | tls_key_share_derive_dhe(struct tls_key_share *ks, | ||
| 334 | uint8_t **shared_key, size_t *shared_key_len) | ||
| 335 | { | ||
| 336 | if (ks->dhe == NULL || ks->dhe_peer == NULL) | ||
| 337 | return 0; | ||
| 338 | |||
| 339 | return ssl_kex_derive_dhe(ks->dhe, ks->dhe_peer, shared_key, | ||
| 340 | shared_key_len); | ||
| 252 | } | 341 | } |
| 253 | 342 | ||
| 254 | static int | 343 | static int |
| @@ -298,6 +387,10 @@ tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key, | |||
| 298 | 387 | ||
| 299 | *shared_key_len = 0; | 388 | *shared_key_len = 0; |
| 300 | 389 | ||
| 390 | if (ks->nid == NID_dhKeyAgreement) | ||
| 391 | return tls_key_share_derive_dhe(ks, shared_key, | ||
| 392 | shared_key_len); | ||
| 393 | |||
| 301 | if (ks->nid == NID_X25519) | 394 | if (ks->nid == NID_X25519) |
| 302 | return tls_key_share_derive_x25519(ks, shared_key, | 395 | return tls_key_share_derive_x25519(ks, shared_key, |
| 303 | shared_key_len); | 396 | shared_key_len); |
