Whamcloud - gitweb
LU-8602 gss: support OpenSSL 1.1 92/33592/4
authorSebastien Buisson <sbuisson@ddn.com>
Tue, 6 Nov 2018 15:31:43 +0000 (15:31 +0000)
committerOleg Drokin <green@whamcloud.com>
Sat, 17 Nov 2018 01:25:21 +0000 (01:25 +0000)
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>
lustre/autoconf/lustre-core.m4
lustre/utils/gss/lgss_sk.c
lustre/utils/gss/sk_utils.c
lustre/utils/gss/sk_utils.h

index d751e49..0e58b7b 100644 (file)
@@ -331,9 +331,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
 
        int main(void) {
                int rc;
 
        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])],
        }
 ])],[AC_DEFINE(HAVE_OPENSSL_SSK, 1,
               [OpenSSL HMAC functions needed for SSK])],
index 4b3d366..d6d9959 100644 (file)
@@ -298,7 +298,7 @@ int main(int argc, char **argv)
        int opt;
        enum sk_key_type type = SK_TYPE_INVALID;
        bool generate_prime = false;
        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'},
 
        static struct option long_opts[] = {
        { .name = "crypt",      .has_arg = required_argument, .val = 'c'},
@@ -556,20 +556,38 @@ int main(int argc, char **argv)
        }
 
        if (generate_prime) {
        }
 
        if (generate_prime) {
+               const BIGNUM *p;
+               int rc;
+
                printf("Generating DH parameters, this can take a while...\n");
                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;
                }
                        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;
                }
                        fprintf(stderr,
                                "error: convert BIGNUM p to binary failed\n");
                        goto error;
                }
+
+               DH_free(dh);
        }
 
        if (write_config_file(modify ?: output, config, modify))
        }
 
        if (write_config_file(modify ?: output, config, modify))
@@ -578,6 +596,7 @@ int main(int argc, char **argv)
        return EXIT_SUCCESS;
 
 error:
        return EXIT_SUCCESS;
 
 error:
+       DH_free(dh);
        free(config);
        return EXIT_FAILURE;
 }
        free(config);
        return EXIT_FAILURE;
 }
index 4b4a911..eca33ba 100644 (file)
@@ -691,6 +691,8 @@ out_err:
 uint32_t sk_gen_params(struct sk_cred *skc)
 {
        uint32_t random;
 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
        int rc;
 
        /* Random value used by both the request and response as part of the
@@ -716,23 +718,28 @@ uint32_t sk_gen_params(struct sk_cred *skc)
                return GSS_S_FAILURE;
        }
 
                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 */
                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;
        }
                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;
        }
 
                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);
        /* 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);
@@ -748,14 +755,15 @@ uint32_t sk_gen_params(struct sk_cred *skc)
                return GSS_S_FAILURE;
        }
 
                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;
        }
 
        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;
 }
 
        return GSS_S_COMPLETE;
 }
@@ -797,7 +805,7 @@ static inline const EVP_MD *sk_hash_to_evp_md(enum cfs_crypto_hash_alg alg)
 int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
                 const EVP_MD *hash_alg, gss_buffer_desc *hmac)
 {
 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;
        unsigned int hashlen = EVP_MD_size(hash_alg);
        int i;
        int rc = -1;
@@ -807,7 +815,7 @@ int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
                return -1;
        }
 
                return -1;
        }
 
-       HMAC_CTX_init(&hctx);
+       hctx = HMAC_CTX_new();
 
        hmac->length = hashlen;
        hmac->value = malloc(hashlen);
 
        hmac->length = hashlen;
        hmac->value = malloc(hashlen);
@@ -816,20 +824,20 @@ int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
                goto out;
        }
 
                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++) {
                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 */
                        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;
        }
                printerr(0, "Failed to finalize HMAC\n");
                goto out;
        }
@@ -841,7 +849,7 @@ int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs,
 
        rc = 0;
 out:
 
        rc = 0;
 out:
-       HMAC_CTX_cleanup(&hctx);
+       HMAC_CTX_free(hctx);
        return rc;
 }
 
        return rc;
 }
 
index 75daee3..e20d12d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/lustre/lustre_idl.h>
 #include <openssl/dh.h>
 #include <openssl/evp.h>
 #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>
 #include <sys/types.h>
 
 #include <libcfs/libcfs_crypto.h>
 #define LL_CRYPTO_MAX_NAME 64
 #endif
 
 #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
 /* Some limits and defaults */
 #define SK_CONF_VERSION 1
 #define SK_MSG_VERSION 1