![]() |
TrustCore SDK NanoCrypto API reference
version 7.0
|
All the explanatory write-up was added after the 5.3.1 release, and should be eng-reviewed for accuracy and appropriateness.
In the standard DH scenario, two participants publicly negotiate a Generator value and a Large Prime modulus value. In private, both participants then select a random number (their private key). Using these values, each participant generates a public key: the Generator raised to the power of the private key, modulo the Large Prime. (This calculation is presented in the table below.) Each participant then sends its public key to the other. Using these openly communicated values and their private keys, each participant can generate an identical shared secret value. (The calculation is presented in the table below.)
Using this shared secret value as a key, both parties can encrypt their subsequent communications using a symmetric cipher. The following table summarizes the standard DH protocol and how one uses the fundamental DigiCert TrustCore SDK DH API to implement that protocol. In this table, you will see references to a "client" and a "server." In this case, the client is the initiator of the negotiation, and the server is the responder to the initial request.
Step | Action | Role of Client and Server |
---|---|---|
1 | Call DH_allocate(). | Both client and server use this function to allocate and initialize a diffieHellmanContext structure, which is used by the DH API to maintain DH context information. For details, see the description of the diffieHellmanContext structure and its members. |
2 | Negotiate the Generator and the Large Prime. | During this step of the protocol, the client should contact the server and negotiate the values for the Large Prime and the Generator. The security of the protocol depends on the Large Prime being truly large. For the Generator, agree on a primitive root of the Large Prime. To enhance security, choose a Generator that generates a large subgroup of the multiplicative group mod Large Prime; a single-digit prime number is the usual choice. To generate suitable Generator and Large Prime values for the negotiation, use the functions, DH_getP() and DH_getG(). When exchanging Generator and Large Prime values with a peer, use the ASN.1 object and identifiers specified in the RSA document, PKCS #3: Diffie-Hellman Key-Agreement Standard, a publication of RSA Laboratories. Section 9 of the publication defines the following: dhKeyAgreement OBJECT IDENTIFIER ::= { pkcs-3 1 pkcs-3 OBJECT IDENTIFIER ::= { iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 3 } DHParameter ::= SEQUENCE { prime INTEGER, – p base INTEGER, – g privateValueLength INTEGER OPTIONAL } |
3 | Call DH_setPG(). | Both the client and server use this function to add the Generator and the Large Prime to the context information stored in their respective diffieHellmanContext structures. The Generator and the Large Prime are stored under the members, dh_g and dh_p . The DH_setPG() function also selects the caller's Private Key, a random number. After selecting the caller's Private Key, this function calculates the caller's Public Key, using the formula:![]()
|
4 | Send your Public Key to the peer. | To obtain this Public Key, read the dh_f member of the diffieHellmanContext structure after a successful call to DH_setPG().
|
5 | Receive the Public Key from the peer. | Upon receiving the peer's Public Key, both client and server store it in the dh_e member of their respective diffieHellmanContext structures.
|
6 | Call DH_computeKeyExchange(). | After the successful completion of a DH_computeKeyExchange() call, both client and server can find the shared secret in the dh_k member of their respective diffieHellmanContext structures.![]()
|
7 | DH_freeDhContext() | After you are done with the shared secret or have copied it to a secure location, use DH_freeDhContext() to free the diffieHellmanContext structure allocated by the call to DH_allocate(). |
Before negotiating with the server for the Generator and Large Prime values, the client calls DH_allocateClient(), which does the following: +# Allocates a diffieHellmanContext
structure for the client. +# Chooses a Large Prime value, which it stores in diffieHellmanContext::dh_p
member. +# Chooses a private key for the client, which it stores in diffieHellmanContext::dh_y
member.
Calling DH_allocateClient() does not choose a Generator value. To get a Generator value for your negotiation with the server, call DH_getG(). After completing the negotiation with the server for the Generator and Large Prime, the client continues the protocol from step 3 in the table above.
After receiving a request from a client, the server calls DH_allocateServer(), which does the following:
diffieHellmanContext
structure.diffieHellmanContext::dh_g
.diffieHellmanContext::dh_p
.diffieHellmanContext::dh_y
.diffieHellmanContext::dh_f
.The DH_allocateServer() function's default operation assumes that the negotiation over the Generator and Large Prime modulus value consists of the server telling the client what the values will be. If that is the case, the server continues the protocol from step 4 in the table above. If that is not the case — that is, if the server truly negotiates these values with the client — the server picks up the protocol from step 3 in the table above.