static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { DH *dh = NULL; DH_PKEY_CTX *dctx = ctx->data; BN_GENCB *pcb, cb; int ret; if (dctx->rfc5114_param) { switch (dctx->rfc5114_param) { case 1: dh = DH_get_1024_160(); break; case 2: dh = DH_get_2048_224(); break; case 3: dh = DH_get_2048_256(); break; default: return -2; } EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); return 1; } if (ctx->pkey_gencb) { pcb = &cb; evp_pkey_set_cb_translate(pcb, ctx); } else pcb = NULL; #ifndef OPENSSL_NO_DSA if (dctx->use_dsa) { DSA *dsa_dh; dsa_dh = dsa_dh_generate(dctx, pcb); if (!dsa_dh) return 0; dh = DSA_dup_DH(dsa_dh); DSA_free(dsa_dh); if (!dh) return 0; EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); return 1; } #endif dh = DH_new(); if (!dh) return 0; ret = DH_generate_parameters_ex(dh, dctx->prime_len, dctx->generator, pcb); if (ret) EVP_PKEY_assign_DH(pkey, dh); else DH_free(dh); return ret; }
static int run_rfc5114_tests(void) { int i; DH *dhA = NULL; DH *dhB = NULL; unsigned char *Z1 = NULL; unsigned char *Z2 = NULL; const rfc5114_td *td = NULL; BIGNUM *bady = NULL, *priv_key = NULL, *pub_key = NULL; for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) { td = rfctd + i; /* Set up DH structures setting key components */ dhA = td->get_param(); dhB = td->get_param(); if ((dhA == NULL) || (dhB == NULL)) goto bad_err; priv_key = BN_bin2bn(td->xA, td->xA_len, NULL); pub_key = BN_bin2bn(td->yA, td->yA_len, NULL); if (priv_key == NULL || pub_key == NULL || !DH_set0_key(dhA, pub_key, priv_key)) goto bad_err; priv_key = BN_bin2bn(td->xB, td->xB_len, NULL); pub_key = BN_bin2bn(td->yB, td->yB_len, NULL); if (priv_key == NULL || pub_key == NULL || !DH_set0_key(dhB, pub_key, priv_key)) goto bad_err; priv_key = pub_key = NULL; if ((td->Z_len != (size_t)DH_size(dhA)) || (td->Z_len != (size_t)DH_size(dhB))) goto err; Z1 = OPENSSL_malloc(DH_size(dhA)); Z2 = OPENSSL_malloc(DH_size(dhB)); if ((Z1 == NULL) || (Z2 == NULL)) goto bad_err; /* * Work out shared secrets using both sides and compare with expected * values. */ DH_get0_key(dhB, &pub_key, NULL); if (DH_compute_key(Z1, pub_key, dhA) == -1) { pub_key = NULL; goto bad_err; } DH_get0_key(dhA, &pub_key, NULL); if (DH_compute_key(Z2, pub_key, dhB) == -1) { pub_key = NULL; goto bad_err; } pub_key = NULL; if (memcmp(Z1, td->Z, td->Z_len)) goto err; if (memcmp(Z2, td->Z, td->Z_len)) goto err; printf("RFC5114 parameter test %d OK\n", i + 1); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); OPENSSL_free(Z2); dhA = NULL; dhB = NULL; Z1 = NULL; Z2 = NULL; } /* Now i == OSSL_NELEM(rfctd) */ /* RFC5114 uses unsafe primes, so now test an invalid y value */ dhA = DH_get_2048_224(); if (dhA == NULL) goto bad_err; Z1 = OPENSSL_malloc(DH_size(dhA)); if (Z1 == NULL) goto bad_err; bady = BN_bin2bn(dhtest_rfc5114_2048_224_bad_y, sizeof(dhtest_rfc5114_2048_224_bad_y), NULL); if (bady == NULL) goto bad_err; if (!DH_generate_key(dhA)) goto bad_err; if (DH_compute_key(Z1, bady, dhA) != -1) { /* * DH_compute_key should fail with -1. If we get here we unexpectedly * allowed an invalid y value */ goto err; } /* We'll have a stale error on the queue from the above test so clear it */ ERR_clear_error(); printf("RFC5114 parameter test %d OK\n", i + 1); BN_free(bady); DH_free(dhA); OPENSSL_free(Z1); return 1; bad_err: BN_free(bady); DH_free(dhA); DH_free(dhB); BN_free(pub_key); BN_free(priv_key); OPENSSL_free(Z1); OPENSSL_free(Z2); fprintf(stderr, "Initialisation error RFC5114 set %d\n", i + 1); ERR_print_errors_fp(stderr); return 0; err: BN_free(bady); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); OPENSSL_free(Z2); fprintf(stderr, "Test failed RFC5114 set %d\n", i + 1); return 0; }