{
    "content": [
        {
            "type": "text",
            "text": "# EVP_PKEY-DH (info)\n\n## NAME\n\nEVPPKEY-DH, EVPPKEY-DHX, EVPKEYMGMT-DH - EVPPKEY DH and DHX keytype and algorithm support\n\n## DESCRIPTION\n\nFor DH FFC key agreement, two classes of domain parameters can be used:\n\"safe\" domain parameters that are associated with approved named safe-\nprime groups, and a class of \"FIPS 186-type\" domain parameters. FIPS\n186-type domain parameters should only be used for backward\ncompatibility with existing applications that cannot be upgraded to use\nthe approved safe-prime groups.\n\n## Sections\n\n- **NAME**\n- **DESCRIPTION**\n- **EXAMPLES**\n- **CONFORMING TO**\n- **SEE ALSO**\n- **COPYRIGHT**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "EVP_PKEY-DH",
        "section": "",
        "mode": "info",
        "summary": "EVPPKEY-DH, EVPPKEY-DHX, EVPKEYMGMT-DH - EVPPKEY DH and DHX keytype and algorithm support",
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [
            "An EVPPKEY context can be obtained by calling:",
            "EVPPKEYCTX *pctx = EVPPKEYCTXnewfromname(NULL, \"DH\", NULL);",
            "A DH key can be generated with a named safe prime group by calling:",
            "int privlen = 2 * 112;",
            "OSSLPARAM params[3];",
            "EVPPKEY *pkey = NULL;",
            "EVPPKEYCTX *pctx = EVPPKEYCTXnewfromname(NULL, \"DH\", NULL);",
            "params[0] = OSSLPARAMconstructutf8string(\"group\", \"ffdhe2048\", 0);",
            "/* \"privlen\" is optional */",
            "params[1] = OSSLPARAMconstructint(\"privlen\", &privlen);",
            "params[2] = OSSLPARAMconstructend();",
            "EVPPKEYkeygeninit(pctx);",
            "EVPPKEYCTXsetparams(pctx, params);",
            "EVPPKEYgenerate(pctx, &pkey);",
            "...",
            "EVPPKEYfree(pkey);",
            "EVPPKEYCTXfree(pctx);",
            "DHX domain parameters can be generated according to FIPS 186-4 by",
            "calling:",
            "int gindex = 2;",
            "unsigned int pbits = 2048;",
            "unsigned int qbits = 256;",
            "OSSLPARAM params[6];",
            "EVPPKEY *paramkey = NULL;",
            "EVPPKEYCTX *pctx = NULL;",
            "pctx = EVPPKEYCTXnewfromname(NULL, \"DHX\", NULL);",
            "EVPPKEYparamgeninit(pctx);",
            "params[0] = OSSLPARAMconstructuint(\"pbits\", &pbits);",
            "params[1] = OSSLPARAMconstructuint(\"qbits\", &qbits);",
            "params[2] = OSSLPARAMconstructint(\"gindex\", &gindex);",
            "params[3] = OSSLPARAMconstructutf8string(\"type\", \"fips1864\", 0);",
            "params[4] = OSSLPARAMconstructutf8string(\"digest\", \"SHA256\", 0);",
            "params[5] = OSSLPARAMconstructend();",
            "EVPPKEYCTXsetparams(pctx, params);",
            "EVPPKEYgenerate(pctx, &paramkey);",
            "EVPPKEYprintparams(bioout, paramkey, 0, NULL);",
            "...",
            "EVPPKEYfree(paramkey);",
            "EVPPKEYCTXfree(pctx);",
            "A DH key can be generated using domain parameters by calling:",
            "EVPPKEY *key = NULL;",
            "EVPPKEYCTX *gctx = EVPPKEYCTXnewfrompkey(NULL, paramkey, NULL);",
            "EVPPKEYkeygeninit(gctx);",
            "EVPPKEYgenerate(gctx, &key);",
            "EVPPKEYprintprivate(bioout, key, 0, NULL);",
            "...",
            "EVPPKEYfree(key);",
            "EVPPKEYCTXfree(gctx);",
            "To validate FIPS 186-4 DHX domain parameters decoded from PEM or DER",
            "data, additional values used during generation may be required to be",
            "set into the key.",
            "EVPPKEYtodata(), OSSLPARAMmerge(), and EVPPKEYfromdata() are",
            "useful to add these parameters to the original key or domain parameters",
            "before the actual validation. In production code the return values",
            "should be checked.",
            "EVPPKEY *receiveddomp = ...; /* parameters received and decoded */",
            "unsigned char *seed = ...;     /* and additional parameters received */",
            "sizet seedlen = ...;          /* by other means, required */",
            "int gindex = ...;              /* for the validation */",
            "int pcounter = ...;",
            "int hindex = ...;",
            "OSSLPARAM extraparams[4];",
            "OSSLPARAM *domainparams = NULL;",
            "OSSLPARAM *mergedparams = NULL;",
            "EVPPKEYCTX *ctx = NULL, *validatectx = NULL;",
            "EVPPKEY *completedomp = NULL;",
            "EVPPKEYtodata(receiveddomp, OSSLKEYMGMTSELECTDOMAINPARAMETERS,",
            "&domainparams);",
            "extraparams[0] = OSSLPARAMconstructoctetstring(\"seed\", seed, seedlen);",
            "/*",
            "* NOTE: For unverifiable g use \"hindex\" instead of \"gindex\"",
            "* extraparams[1] = OSSLPARAMconstructint(\"hindex\", &hindex);",
            "*/",
            "extraparams[1] = OSSLPARAMconstructint(\"gindex\", &gindex);",
            "extraparams[2] = OSSLPARAMconstructint(\"pcounter\", &pcounter);",
            "extraparams[3] = OSSLPARAMconstructend();",
            "mergedparams = OSSLPARAMmerge(domainparams, extraparams);",
            "ctx = EVPPKEYCTXnewfromname(NULL, \"DHX\", NULL);",
            "EVPPKEYfromdatainit(ctx);",
            "EVPPKEYfromdata(ctx, &completedomp, OSSLKEYMGMTSELECTALL,",
            "mergedparams);",
            "validatectx = EVPPKEYCTXnewfrompkey(NULL, completedomp, NULL);",
            "if (EVPPKEYparamcheck(validatectx) > 0)",
            "/* validationpassed(); */",
            "else",
            "/* validationfailed(); */",
            "OSSLPARAMfree(domainparams);",
            "OSSLPARAMfree(mergedparams);",
            "EVPPKEYCTXfree(ctx);",
            "EVPPKEYCTXfree(validatectx);",
            "EVPPKEYfree(completedomp);"
        ],
        "see_also": [
            {
                "name": "EVPPKEY-FFC",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/EVPPKEY-FFC/7/json"
            },
            {
                "name": "EVPKEYEXCH-DH",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/EVPKEYEXCH-DH/7/json"
            },
            {
                "name": "EVPPKEY",
                "section": "3",
                "url": "https://www.chedong.com/phpMan.php/man/EVPPKEY/3/json"
            },
            {
                "name": "provider-keymgmt",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/provider-keymgmt/7/json"
            },
            {
                "name": "EVPKEYMGMT",
                "section": "3",
                "url": "https://www.chedong.com/phpMan.php/man/EVPKEYMGMT/3/json"
            },
            {
                "name": "OSSLPROVIDER-default",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/OSSLPROVIDER-default/7/json"
            },
            {
                "name": "OSSLPROVIDER-FIPS",
                "section": "7",
                "url": "https://www.chedong.com/phpMan.php/man/OSSLPROVIDER-FIPS/7/json"
            }
        ],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 98,
                "subsections": []
            },
            {
                "name": "EXAMPLES",
                "lines": 113,
                "subsections": []
            },
            {
                "name": "CONFORMING TO",
                "lines": 17,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "COPYRIGHT",
                "lines": 8,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "EVPPKEY-DH, EVPPKEY-DHX, EVPKEYMGMT-DH - EVPPKEY DH and DHX keytype\nand algorithm support\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "For DH FFC key agreement, two classes of domain parameters can be used:\n\"safe\" domain parameters that are associated with approved named safe-\nprime groups, and a class of \"FIPS 186-type\" domain parameters. FIPS\n186-type domain parameters should only be used for backward\ncompatibility with existing applications that cannot be upgraded to use\nthe approved safe-prime groups.\n\nSee EVPPKEY-FFC(7) for more information about FFC keys.\n\nThe DH key type uses PKCS#3 format which saves p and g, but not the 'q'\nvalue.  The DHX key type uses X9.42 format which saves the value of 'q'\nand this must be used for FIPS186-4.\n\nFor DHX that is not a named group the FIPS186-4 standard specifies that\nthe values used for FFC parameter generation are also required for\nparameter validation. This means that optional FFC domain parameter\nvalues for seed, pcounter and gindex or hindex may need to be stored\nfor validation purposes.  For DHX the seed and pcounter can be stored\nin ASN1 data (but the gindex or hindex can not be stored).\n\nDH and DHX domain parameters\nIn addition to the common FCC parameters that all FFC keytypes should\nsupport (see \"FFC parameters\" in EVPPKEY-FFC(7)) the DHX and DH\nkeytype implementations support the following:\n\n\"group\" (OSSLPKEYPARAMGROUPNAME) <UTF8 string>\nSets or gets a string that associates a DH or DHX named safe prime\ngroup with known values for p, q and g.\n\nThe following values can be used by the OpenSSL's default and FIPS\nproviders: \"ffdhe2048\", \"ffdhe3072\", \"ffdhe4096\", \"ffdhe6144\",\n\"ffdhe8192\", \"modp2048\", \"modp3072\", \"modp4096\", \"modp6144\",\n\"modp8192\".\n\nThe following additional values can also be used by OpenSSL's\ndefault provider: \"modp1536\", \"dh1024160\", \"dh2048224\",\n\"dh2048256\".\n\nDH/DHX named groups can be easily validated since the parameters\nare well known.  For protocols that only transfer p and g the value\nof q can also be retrieved.\n\nDH and DHX additional parameters\n\"encoded-pub-key\" (OSSLPKEYPARAMENCODEDPUBLICKEY) <octet string>\nUsed for getting and setting the encoding of the DH public key used\nin a key exchange message for the TLS protocol.  See\nEVPPKEYset1encodedpublickey() and\nEVPPKEYget1encodedpublickey().\n\nDH additional domain parameters\n\"safeprime-generator\" (OSSLPKEYPARAMDHGENERATOR) <integer>\nUsed for DH generation of safe primes using the old safe prime\ngenerator code.  The default value is 2.  It is recommended to use\na named safe prime group instead, if domain parameter validation is\nrequired.\n\nRandomly generated safe primes are not allowed by FIPS, so setting\nthis value for the OpenSSL FIPS provider will instead choose a\nnamed safe prime group based on the size of p.\n\nDH and DHX domain parameter / key generation parameters\nIn addition to the common FFC key generation parameters that all FFC\nkey types should support (see \"FFC key generation parameters\" in\nEVPPKEY-FFC(7)) the DH and DHX keytype implementation supports the\nfollowing:\n\n\"type\" (OSSLPKEYPARAMFFCTYPE) <UTF8 string>\nSets the type of parameter generation. For DH valid values are:\n\n\"fips1864\"\n\"default\"\n\"fips1862\"\nThese are described in \"FFC key generation parameters\" in\nEVPPKEY-FFC(7)\n\n\"group\"\nThis specifies that a named safe prime name will be chosen\nusing the \"pbits\" type.\n\n\"generator\"\nA safe prime generator. See the \"safeprime-generator\" type\nabove.  This is only valid for DH keys.\n\n\"pbits\" (OSSLPKEYPARAMFFCPBITS) <unsigned integer>\nSets the size (in bits) of the prime 'p'.\n\nFor \"fips1864\" this must be 2048.  For \"fips1862\" this must be\n1024.  For \"group\" this can be any one of 2048, 3072, 4096, 6144 or\n8192.\n\n\"privlen\" (OSSLPKEYPARAMDHPRIVLEN) <integer>\nAn optional value to set the maximum length of the generated\nprivate key.  The default value used if this is not set is the\nmaximum value of BNnumbits(q)). The minimum value that this can\nbe set to is 2 * s.  Where s is the security strength of the key\nwhich has values of 112, 128, 152, 176 and 200 for key sizes of\n2048, 3072, 4096, 6144 and 8192.\n",
                "subsections": []
            },
            "EXAMPLES": {
                "content": "An EVPPKEY context can be obtained by calling:\n\nEVPPKEYCTX *pctx = EVPPKEYCTXnewfromname(NULL, \"DH\", NULL);\n\nA DH key can be generated with a named safe prime group by calling:\n\nint privlen = 2 * 112;\nOSSLPARAM params[3];\nEVPPKEY *pkey = NULL;\nEVPPKEYCTX *pctx = EVPPKEYCTXnewfromname(NULL, \"DH\", NULL);\n\nparams[0] = OSSLPARAMconstructutf8string(\"group\", \"ffdhe2048\", 0);\n/* \"privlen\" is optional */\nparams[1] = OSSLPARAMconstructint(\"privlen\", &privlen);\nparams[2] = OSSLPARAMconstructend();\n\nEVPPKEYkeygeninit(pctx);\nEVPPKEYCTXsetparams(pctx, params);\nEVPPKEYgenerate(pctx, &pkey);\n...\nEVPPKEYfree(pkey);\nEVPPKEYCTXfree(pctx);\n\nDHX domain parameters can be generated according to FIPS 186-4 by\ncalling:\n\nint gindex = 2;\nunsigned int pbits = 2048;\nunsigned int qbits = 256;\nOSSLPARAM params[6];\nEVPPKEY *paramkey = NULL;\nEVPPKEYCTX *pctx = NULL;\n\npctx = EVPPKEYCTXnewfromname(NULL, \"DHX\", NULL);\nEVPPKEYparamgeninit(pctx);\n\nparams[0] = OSSLPARAMconstructuint(\"pbits\", &pbits);\nparams[1] = OSSLPARAMconstructuint(\"qbits\", &qbits);\nparams[2] = OSSLPARAMconstructint(\"gindex\", &gindex);\nparams[3] = OSSLPARAMconstructutf8string(\"type\", \"fips1864\", 0);\nparams[4] = OSSLPARAMconstructutf8string(\"digest\", \"SHA256\", 0);\nparams[5] = OSSLPARAMconstructend();\nEVPPKEYCTXsetparams(pctx, params);\n\nEVPPKEYgenerate(pctx, &paramkey);\n\nEVPPKEYprintparams(bioout, paramkey, 0, NULL);\n...\nEVPPKEYfree(paramkey);\nEVPPKEYCTXfree(pctx);\n\nA DH key can be generated using domain parameters by calling:\n\nEVPPKEY *key = NULL;\nEVPPKEYCTX *gctx = EVPPKEYCTXnewfrompkey(NULL, paramkey, NULL);\n\nEVPPKEYkeygeninit(gctx);\nEVPPKEYgenerate(gctx, &key);\nEVPPKEYprintprivate(bioout, key, 0, NULL);\n...\nEVPPKEYfree(key);\nEVPPKEYCTXfree(gctx);\n\nTo validate FIPS 186-4 DHX domain parameters decoded from PEM or DER\ndata, additional values used during generation may be required to be\nset into the key.\n\nEVPPKEYtodata(), OSSLPARAMmerge(), and EVPPKEYfromdata() are\nuseful to add these parameters to the original key or domain parameters\nbefore the actual validation. In production code the return values\nshould be checked.\n\nEVPPKEY *receiveddomp = ...; /* parameters received and decoded */\nunsigned char *seed = ...;     /* and additional parameters received */\nsizet seedlen = ...;          /* by other means, required */\nint gindex = ...;              /* for the validation */\nint pcounter = ...;\nint hindex = ...;\nOSSLPARAM extraparams[4];\nOSSLPARAM *domainparams = NULL;\nOSSLPARAM *mergedparams = NULL;\nEVPPKEYCTX *ctx = NULL, *validatectx = NULL;\nEVPPKEY *completedomp = NULL;\n\nEVPPKEYtodata(receiveddomp, OSSLKEYMGMTSELECTDOMAINPARAMETERS,\n&domainparams);\nextraparams[0] = OSSLPARAMconstructoctetstring(\"seed\", seed, seedlen);\n/*\n* NOTE: For unverifiable g use \"hindex\" instead of \"gindex\"\n* extraparams[1] = OSSLPARAMconstructint(\"hindex\", &hindex);\n*/\nextraparams[1] = OSSLPARAMconstructint(\"gindex\", &gindex);\nextraparams[2] = OSSLPARAMconstructint(\"pcounter\", &pcounter);\nextraparams[3] = OSSLPARAMconstructend();\nmergedparams = OSSLPARAMmerge(domainparams, extraparams);\n\nctx = EVPPKEYCTXnewfromname(NULL, \"DHX\", NULL);\nEVPPKEYfromdatainit(ctx);\nEVPPKEYfromdata(ctx, &completedomp, OSSLKEYMGMTSELECTALL,\nmergedparams);\n\nvalidatectx = EVPPKEYCTXnewfrompkey(NULL, completedomp, NULL);\nif (EVPPKEYparamcheck(validatectx) > 0)\n/* validationpassed(); */\nelse\n/* validationfailed(); */\n\nOSSLPARAMfree(domainparams);\nOSSLPARAMfree(mergedparams);\nEVPPKEYCTXfree(ctx);\nEVPPKEYCTXfree(validatectx);\nEVPPKEYfree(completedomp);\n",
                "subsections": []
            },
            "CONFORMING TO": {
                "content": "RFC 7919 (TLS ffdhe named safe prime groups)\nRFC 3526 (IKE modp named safe prime groups)\nRFC 5114 (Additional DH named groups for dh1024160\", \"dh2048224\"\nand \"dh2048256\").\n\nThe following sections of SP800-56Ar3:\n\n5.5.1.1 FFC Domain Parameter Selection/Generation\nAppendix D: FFC Safe-prime Groups\n\nThe following sections of FIPS 186-4:\n\nA.1.1.2 Generation of Probable Primes p and q Using an Approved Hash\nFunction.\nA.2.3 Generation of canonical generator g.\nA.2.1 Unverifiable Generation of the Generator g.\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "EVPPKEY-FFC(7), EVPKEYEXCH-DH(7) EVPPKEY(3), provider-keymgmt(7),\nEVPKEYMGMT(3), OSSLPROVIDER-default(7), OSSLPROVIDER-FIPS(7)\n",
                "subsections": []
            },
            "COPYRIGHT": {
                "content": "Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.\n\nLicensed under the Apache License 2.0 (the \"License\").  You may not use\nthis file except in compliance with the License.  You can obtain a copy\nin the file LICENSE in the source distribution or at\n<https://www.openssl.org/source/license.html>.\n\n3.0.2                             2026-06-02                 EVPPKEY-DH(7SSL)",
                "subsections": []
            }
        }
    }
}