From: Sebastien Buisson Date: Tue, 6 Nov 2018 15:31:43 +0000 (+0000) Subject: LU-8602 gss: support OpenSSL 1.1 X-Git-Tag: 2.12.0-RC1~43 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=f44a953b30b2a439a9477ed5ecf599e172366493;hp=87383c55e74a219e72bcf861a2d2e81d978a927f LU-8602 gss: support OpenSSL 1.1 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 Change-Id: I1fc9b77fc44976f4b1fb3a58ae7db9c20a96b3e9 Reviewed-on: https://review.whamcloud.com/33592 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index d751e49..0e58b7b 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -331,9 +331,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ 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])], diff --git a/lustre/utils/gss/lgss_sk.c b/lustre/utils/gss/lgss_sk.c index 4b3d366..d6d9959 100644 --- a/lustre/utils/gss/lgss_sk.c +++ b/lustre/utils/gss/lgss_sk.c @@ -298,7 +298,7 @@ int main(int argc, char **argv) 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'}, @@ -556,20 +556,38 @@ int main(int argc, char **argv) } 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)) @@ -578,6 +596,7 @@ int main(int argc, char **argv) return EXIT_SUCCESS; error: + DH_free(dh); free(config); return EXIT_FAILURE; } diff --git a/lustre/utils/gss/sk_utils.c b/lustre/utils/gss/sk_utils.c index 4b4a911..eca33ba 100644 --- a/lustre/utils/gss/sk_utils.c +++ b/lustre/utils/gss/sk_utils.c @@ -691,6 +691,8 @@ out_err: 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 @@ -716,23 +718,28 @@ uint32_t sk_gen_params(struct sk_cred *skc) 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); @@ -748,14 +755,15 @@ uint32_t sk_gen_params(struct sk_cred *skc) 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; } @@ -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) { - HMAC_CTX hctx; + HMAC_CTX *hctx; 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; } - HMAC_CTX_init(&hctx); + hctx = HMAC_CTX_new(); 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; } - 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; } @@ -841,7 +849,7 @@ int sk_sign_bufs(gss_buffer_desc *key, gss_buffer_desc *bufs, const int numbufs, rc = 0; out: - HMAC_CTX_cleanup(&hctx); + HMAC_CTX_free(hctx); return rc; } diff --git a/lustre/utils/gss/sk_utils.h b/lustre/utils/gss/sk_utils.h index 75daee3..e20d12d 100644 --- a/lustre/utils/gss/sk_utils.h +++ b/lustre/utils/gss/sk_utils.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,74 @@ #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