Allow the internal DH implementation to be overridden
Crypto library wrappers can now override the internal DH (group 5) implementation. As a starting point, this is done with OpenSSL. The new mechanism is currently available only for WPS (i.e., IKEv2 still depends on the internal DH implementation).
This commit is contained in:
parent
dd01b1ff9d
commit
f042122a57
11 changed files with 209 additions and 11 deletions
|
@ -449,6 +449,7 @@ OBJS_p += ../src/crypto/fips_prf_gnutls.o
|
|||
endif
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), internal)
|
||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
||||
|
@ -456,6 +457,7 @@ OBJS += ../src/crypto/crypto_libtomcrypt.o
|
|||
OBJS_p += ../src/crypto/crypto_libtomcrypt.o
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_CRYPTO), internal)
|
||||
OBJS += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
|
||||
|
@ -477,6 +479,7 @@ CONFIG_INTERNAL_MD4=y
|
|||
CONFIG_INTERNAL_MD5=y
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
endif
|
||||
else
|
||||
|
@ -516,12 +519,20 @@ OBJS += ../src/crypto/sha256-internal.o
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_INTERNAL_DH_GROUP5
|
||||
ifdef NEED_DH_GROUPS
|
||||
OBJS += ../src/crypto/dh_groups.o
|
||||
OBJS += ../src/crypto/dh_group5.o
|
||||
ifdef NEED_DH_GROUPS_ALL
|
||||
CFLAGS += -DALL_DH_GROUPS
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifdef NEED_DH_GROUPS_ALL
|
||||
OBJS += ../src/crypto/dh_groups.o
|
||||
CFLAGS += -DALL_DH_GROUPS
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef NEED_T_PRF
|
||||
SHA1OBJS += ../src/crypto/sha1-tprf.o
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#include <openssl/aes.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "wpabuf.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000
|
||||
|
@ -363,3 +365,98 @@ void crypto_cipher_deinit(struct crypto_cipher *ctx)
|
|||
EVP_CIPHER_CTX_cleanup(&ctx->dec);
|
||||
os_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
|
||||
{
|
||||
DH *dh;
|
||||
struct wpabuf *pubkey = NULL, *privkey = NULL;
|
||||
size_t publen, privlen;
|
||||
|
||||
*priv = NULL;
|
||||
*publ = NULL;
|
||||
|
||||
dh = DH_new();
|
||||
if (dh == NULL)
|
||||
return NULL;
|
||||
|
||||
dh->g = BN_new();
|
||||
if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
|
||||
goto err;
|
||||
|
||||
dh->p = get_rfc3526_prime_1536(NULL);
|
||||
if (dh->p == NULL)
|
||||
goto err;
|
||||
|
||||
if (DH_generate_key(dh) != 1)
|
||||
goto err;
|
||||
|
||||
publen = BN_num_bytes(dh->p);
|
||||
pubkey = wpabuf_alloc(publen);
|
||||
if (pubkey == NULL)
|
||||
goto err;
|
||||
privlen = BN_num_bytes(dh->priv_key);
|
||||
privkey = wpabuf_alloc(privlen);
|
||||
if (privkey == NULL)
|
||||
goto err;
|
||||
|
||||
BN_bn2bin(dh->pub_key, wpabuf_put(pubkey, publen));
|
||||
BN_bn2bin(dh->priv_key, wpabuf_put(privkey, privlen));
|
||||
|
||||
*priv = privkey;
|
||||
*publ = pubkey;
|
||||
return dh;
|
||||
|
||||
err:
|
||||
wpabuf_free(pubkey);
|
||||
wpabuf_free(privkey);
|
||||
DH_free(dh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
|
||||
const struct wpabuf *own_private)
|
||||
{
|
||||
BIGNUM *pub_key;
|
||||
struct wpabuf *res = NULL;
|
||||
size_t rlen;
|
||||
DH *dh = ctx;
|
||||
int keylen;
|
||||
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
pub_key = BN_bin2bn(wpabuf_head(peer_public), wpabuf_len(peer_public),
|
||||
NULL);
|
||||
if (pub_key == NULL)
|
||||
return NULL;
|
||||
|
||||
rlen = DH_size(dh);
|
||||
res = wpabuf_alloc(rlen);
|
||||
if (res == NULL)
|
||||
goto err;
|
||||
|
||||
keylen = DH_compute_key(wpabuf_mhead(res), pub_key, dh);
|
||||
if (keylen < 0)
|
||||
goto err;
|
||||
wpabuf_put(res, keylen);
|
||||
BN_free(pub_key);
|
||||
|
||||
return res;
|
||||
|
||||
err:
|
||||
BN_free(pub_key);
|
||||
wpabuf_free(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void dh5_free(void *ctx)
|
||||
{
|
||||
DH *dh;
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
dh = ctx;
|
||||
DH_free(dh);
|
||||
}
|
||||
|
|
40
src/crypto/dh_group5.c
Normal file
40
src/crypto/dh_group5.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Diffie-Hellman group 5 operations
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "dh_groups.h"
|
||||
#include "dh_group5.h"
|
||||
|
||||
|
||||
void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
|
||||
{
|
||||
*publ = dh_init(dh_groups_get(5), priv);
|
||||
if (*publ == 0)
|
||||
return NULL;
|
||||
return (void *) 1;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
|
||||
const struct wpabuf *own_private)
|
||||
{
|
||||
return dh_derive_shared(peer_public, own_private, dh_groups_get(5));
|
||||
}
|
||||
|
||||
|
||||
void dh5_free(void *ctx)
|
||||
{
|
||||
}
|
23
src/crypto/dh_group5.h
Normal file
23
src/crypto/dh_group5.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Diffie-Hellman group 5 operations
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef DH_GROUP5_H
|
||||
#define DH_GROUP5_H
|
||||
|
||||
void * dh5_init(struct wpabuf **priv, struct wpabuf **publ);
|
||||
struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
|
||||
const struct wpabuf *own_private);
|
||||
void dh5_free(void *ctx);
|
||||
|
||||
#endif /* DH_GROUP5_H */
|
|
@ -15,6 +15,7 @@
|
|||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "dh_group5.h"
|
||||
#include "wps_i.h"
|
||||
#include "wps_dev_attr.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
|
@ -130,6 +131,7 @@ void wps_deinit(struct wps_data *data)
|
|||
os_free(data->new_psk);
|
||||
wps_device_data_free(&data->peer_dev);
|
||||
os_free(data->new_ap_settings);
|
||||
dh5_free(data->dh_ctx);
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,11 @@ struct wps_context {
|
|||
*/
|
||||
u16 oob_dev_pw_id;
|
||||
|
||||
/**
|
||||
* dh_ctx - Context data for Diffie-Hellman operation
|
||||
*/
|
||||
void *dh_ctx;
|
||||
|
||||
/**
|
||||
* dh_privkey - Diffie-Hellman private key
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "dh_groups.h"
|
||||
#include "dh_group5.h"
|
||||
#include "crypto.h"
|
||||
#include "sha256.h"
|
||||
#include "aes_wrap.h"
|
||||
|
@ -31,15 +31,17 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
|
|||
if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
|
||||
wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
|
||||
wps->dh_ctx = wps->wps->dh_ctx;
|
||||
wps->wps->dh_ctx = NULL;
|
||||
pubkey = wpabuf_dup(wps->wps->dh_pubkey);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys");
|
||||
wps->dh_privkey = NULL;
|
||||
pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
|
||||
&wps->dh_privkey);
|
||||
dh5_free(wps->dh_ctx);
|
||||
wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
|
||||
pubkey = wpabuf_zeropad(pubkey, 192);
|
||||
}
|
||||
if (wps->dh_privkey == NULL || pubkey == NULL) {
|
||||
if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
|
||||
"Diffie-Hellman handshake");
|
||||
wpabuf_free(pubkey);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "dh_groups.h"
|
||||
#include "dh_group5.h"
|
||||
#include "sha256.h"
|
||||
#include "aes_wrap.h"
|
||||
#include "crypto.h"
|
||||
|
@ -80,8 +80,9 @@ int wps_derive_keys(struct wps_data *wps)
|
|||
return -1;
|
||||
}
|
||||
|
||||
dh_shared = dh_derive_shared(pubkey, wps->dh_privkey,
|
||||
dh_groups_get(WPS_DH_GROUP));
|
||||
dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey);
|
||||
dh5_free(wps->dh_ctx);
|
||||
wps->dh_ctx = NULL;
|
||||
dh_shared = wpabuf_zeropad(dh_shared, 192);
|
||||
if (dh_shared == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key");
|
||||
|
|
|
@ -105,6 +105,8 @@ struct wps_data {
|
|||
int ext_reg;
|
||||
|
||||
struct wps_credential *new_ap_settings;
|
||||
|
||||
void *dh_ctx;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ OBJS += ../src/utils/wpabuf.o
|
|||
OBJS_p = wpa_passphrase.o
|
||||
OBJS_p += ../src/utils/common.o
|
||||
OBJS_p += ../src/utils/wpa_debug.o
|
||||
OBJS_p += ../src/utils/wpabuf.o
|
||||
OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o
|
||||
|
||||
-include .config
|
||||
|
@ -756,12 +757,14 @@ OBJS += ../src/crypto/fips_prf_gnutls.o
|
|||
endif
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), schannel)
|
||||
OBJS += ../src/crypto/crypto_cryptoapi.o
|
||||
OBJS_p += ../src/crypto/crypto_cryptoapi.o
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), nss)
|
||||
OBJS += ../src/crypto/crypto_nss.o
|
||||
|
@ -770,6 +773,7 @@ CONFIG_INTERNAL_MD4=y
|
|||
ifdef NEED_FIPS186_2_PRF
|
||||
OBJS += ../src/crypto/fips_prf_nss.o
|
||||
endif
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_TLS), internal)
|
||||
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
||||
|
@ -777,6 +781,7 @@ OBJS += ../src/crypto/crypto_libtomcrypt.o
|
|||
OBJS_p += ../src/crypto/crypto_libtomcrypt.o
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_CRYPTO), internal)
|
||||
OBJS += ../src/crypto/crypto_internal.o ../src/tls/bignum.o
|
||||
|
@ -798,6 +803,7 @@ CONFIG_INTERNAL_MD4=y
|
|||
CONFIG_INTERNAL_MD5=y
|
||||
CONFIG_INTERNAL_SHA256=y
|
||||
CONFIG_INTERNAL_RC4=y
|
||||
CONFIG_INTERNAL_DH_GROUP5=y
|
||||
endif
|
||||
ifeq ($(CONFIG_CRYPTO), cryptoapi)
|
||||
OBJS += ../src/crypto/crypto_cryptoapi.o
|
||||
|
@ -997,12 +1003,20 @@ ifdef NEED_AES
|
|||
OBJS += $(AESOBJS)
|
||||
endif
|
||||
|
||||
ifdef CONFIG_INTERNAL_DH_GROUP5
|
||||
ifdef NEED_DH_GROUPS
|
||||
OBJS += ../src/crypto/dh_groups.o
|
||||
OBJS += ../src/crypto/dh_group5.o
|
||||
ifdef NEED_DH_GROUPS_ALL
|
||||
CFLAGS += -DALL_DH_GROUPS
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifdef NEED_DH_GROUPS_ALL
|
||||
OBJS += ../src/crypto/dh_groups.o
|
||||
CFLAGS += -DALL_DH_GROUPS
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef NEED_T_PRF
|
||||
SHA1OBJS += ../src/crypto/sha1-tprf.o
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "blacklist.h"
|
||||
#include "wpa.h"
|
||||
#include "wps_supplicant.h"
|
||||
#include "dh_groups.h"
|
||||
#include "dh_group5.h"
|
||||
|
||||
#define WPS_PIN_SCAN_IGNORE_SEL_REG 3
|
||||
|
||||
|
@ -619,10 +619,11 @@ int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
|
|||
wpabuf_free(wps->dh_pubkey);
|
||||
wpabuf_free(wps->dh_privkey);
|
||||
wps->dh_privkey = NULL;
|
||||
wps->dh_pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
|
||||
&wps->dh_privkey);
|
||||
wps->dh_pubkey = NULL;
|
||||
dh5_free(wps->dh_ctx);
|
||||
wps->dh_ctx = dh5_init(&wps->dh_privkey, &wps->dh_pubkey);
|
||||
wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
|
||||
if (wps->dh_pubkey == NULL) {
|
||||
if (wps->dh_ctx == NULL || wps->dh_pubkey == NULL) {
|
||||
wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
|
||||
"Diffie-Hellman handshake");
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue