Add support for OpenSSL 1.1, used by default on Ubuntu 18.04.
It mainly consists in changing the way variables of type DH
and HMAC_CTX are used.
Test-Parameters: testlist=sanity-sec envdefinitions=SHARED_KEY=true
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I1fc9b77fc44976f4b1fb3a58ae7db9c20a96b3e9
Reviewed-on: https://review.whamcloud.com/33592
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
int main(void) {
int rc;
- HMAC_CTX ctx;
- HMAC_CTX_init(&ctx);
- rc = HMAC_Init_ex(&ctx, "test", 4, EVP_md_null(), NULL);
+ rc = HMAC_Init_ex(NULL, "test", 4, EVP_md_null(), NULL);
}
])],[AC_DEFINE(HAVE_OPENSSL_SSK, 1,
[OpenSSL HMAC functions needed for SSK])],
int opt;
enum sk_key_type type = SK_TYPE_INVALID;
bool generate_prime = false;
- DH *dh;
+ DH *dh = NULL;
static struct option long_opts[] = {
{ .name = "crypt", .has_arg = required_argument, .val = 'c'},
}
if (generate_prime) {
+ const BIGNUM *p;
+ int rc;
+
printf("Generating DH parameters, this can take a while...\n");
- dh = DH_generate_parameters(config->skc_prime_bits,
- SK_GENERATOR, NULL, NULL);
- if (BN_num_bytes(dh->p) > SK_MAX_P_BYTES) {
+ dh = DH_new();
+ if (!dh) {
+ fprintf(stderr, "error: dh cannot be allocated\n");
+ goto error;
+ }
+
+ rc = DH_generate_parameters_ex(dh, config->skc_prime_bits,
+ SK_GENERATOR, NULL);
+ if (rc != 1) {
+ fprintf(stderr, "error generating DH parameters\n");
+ goto error;
+ }
+
+ DH_get0_pqg(dh, &p, NULL, NULL);
+
+ if (BN_num_bytes(p) > SK_MAX_P_BYTES) {
fprintf(stderr, "error: cannot generate DH parameters: "
"requested length %d exceeds maximum %d\n",
config->skc_prime_bits, SK_MAX_P_BYTES * 8);
goto error;
}
- if (BN_bn2bin(dh->p, config->skc_p) != BN_num_bytes(dh->p)) {
+ if (BN_bn2bin(p, config->skc_p) != BN_num_bytes(p)) {
fprintf(stderr,
"error: convert BIGNUM p to binary failed\n");
goto error;
}
+
+ DH_free(dh);
}
if (write_config_file(modify ?: output, config, modify))
return EXIT_SUCCESS;
error:
+ DH_free(dh);
free(config);
return EXIT_FAILURE;
}
uint32_t sk_gen_params(struct sk_cred *skc)
{
uint32_t random;
+ BIGNUM *p, *g;
+ const BIGNUM *pub_key;
int rc;
/* Random value used by both the request and response as part of the
return GSS_S_FAILURE;
}
- skc->sc_params->p = BN_bin2bn(skc->sc_p.value, skc->sc_p.length, NULL);
- if (!skc->sc_params->p) {
+ p = BN_bin2bn(skc->sc_p.value, skc->sc_p.length, NULL);
+ if (!p) {
printerr(0, "Failed to convert binary to BIGNUM\n");
return GSS_S_FAILURE;
}
/* We use a static generator for shared key */
- skc->sc_params->g = BN_new();
- if (!skc->sc_params->g) {
+ g = BN_new();
+ if (!g) {
printerr(0, "Failed to allocate new BIGNUM\n");
return GSS_S_FAILURE;
}
- if (BN_set_word(skc->sc_params->g, SK_GENERATOR) != 1) {
+ if (BN_set_word(g, SK_GENERATOR) != 1) {
printerr(0, "Failed to set g value for DH params\n");
return GSS_S_FAILURE;
}
+ if (!DH_set0_pqg(skc->sc_params, p, NULL, g)) {
+ printerr(0, "Failed to set pqg\n");
+ return GSS_S_FAILURE;
+ }
+
/* Verify that we have a safe prime and valid generator */
if (DH_check(skc->sc_params, &rc) != 1) {
printerr(0, "DH_check() failed: %d\n", rc);
return GSS_S_FAILURE;
}
- skc->sc_pub_key.length = BN_num_bytes(skc->sc_params->pub_key);
+ DH_get0_key(skc->sc_params, &pub_key, NULL);
+ skc->sc_pub_key.length = BN_num_bytes(pub_key);
skc->sc_pub_key.value = malloc(skc->sc_pub_key.length);
if (!skc->sc_pub_key.value) {
printerr(0, "Failed to allocate memory for public key\n");
return GSS_S_FAILURE;
}
- BN_bn2bin(skc->sc_params->pub_key, skc->sc_pub_key.value);
+ BN_bn2bin(pub_key, skc->sc_pub_key.value);
return GSS_S_COMPLETE;
}
int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
const EVP_MD *hash_alg, gss_buffer_desc *hmac)
{
- HMAC_CTX hctx;
+ HMAC_CTX *hctx;
unsigned int hashlen = EVP_MD_size(hash_alg);
int i;
int rc = -1;
return -1;
}
- HMAC_CTX_init(&hctx);
+ hctx = HMAC_CTX_new();
hmac->length = hashlen;
hmac->value = malloc(hashlen);
goto out;
}
- if (HMAC_Init_ex(&hctx, key->value, key->length, hash_alg, NULL) != 1) {
+ if (HMAC_Init_ex(hctx, key->value, key->length, hash_alg, NULL) != 1) {
printerr(0, "Failed to init HMAC\n");
goto out;
}
for (i = 0; i < numbufs; i++) {
- if (HMAC_Update(&hctx, bufs[i].value, bufs[i].length) != 1) {
+ if (HMAC_Update(hctx, bufs[i].value, bufs[i].length) != 1) {
printerr(0, "Failed to update HMAC\n");
goto out;
}
}
/* The result gets populated in hmac */
- if (HMAC_Final(&hctx, hmac->value, &hashlen) != 1) {
+ if (HMAC_Final(hctx, hmac->value, &hashlen) != 1) {
printerr(0, "Failed to finalize HMAC\n");
goto out;
}
rc = 0;
out:
- HMAC_CTX_cleanup(&hctx);
+ HMAC_CTX_free(hctx);
return rc;
}
#include <linux/lustre/lustre_idl.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
+#include <openssl/hmac.h>
#include <sys/types.h>
#include <libcfs/libcfs_crypto.h>
#define LL_CRYPTO_MAX_NAME 64
#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static inline HMAC_CTX *HMAC_CTX_new(void)
+{
+ HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
+
+ if (ctx != NULL)
+ HMAC_CTX_init(ctx);
+ return ctx;
+}
+
+static inline void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+ if (ctx != NULL) {
+ HMAC_CTX_cleanup(ctx);
+ OPENSSL_cleanse(ctx, sizeof(*ctx));
+ OPENSSL_free(ctx);
+ }
+}
+static inline void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q,
+ const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = dh->p;
+ if (q != NULL)
+ *q = dh->q;
+ if (g != NULL)
+ *g = dh->g;
+}
+
+static inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p and g in dh are NULL, the corresponding input
+ * parameters MUST be non-NULL. q may remain NULL.
+ */
+ if ((dh->p == NULL && p == NULL)
+ || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL) {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL) {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ if (q != NULL)
+ dh->length = BN_num_bits(q);
+
+ return 1;
+}
+
+static inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key,
+ const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = dh->pub_key;
+ if (priv_key != NULL)
+ *priv_key = dh->priv_key;
+}
+#endif
+
/* Some limits and defaults */
#define SK_CONF_VERSION 1
#define SK_MSG_VERSION 1