156 const char *pubkey,
size_t pubkey_len,
157 unsigned char *secret_out,
158 size_t secret_bytes_out)
163 if (!dh->pubkey || !dh->seckey)
168 SECKEYPublicKey peer_key;
169 memset(&peer_key, 0,
sizeof(peer_key));
170 peer_key.keyType = dhKey;
171 peer_key.pkcs11ID = CK_INVALID_HANDLE;
173 if (dh->dh_type == DH_TYPE_TLS)
174 peer_key.u.dh.prime.data = tls_dh_prime_data;
176 peer_key.u.dh.prime.data = circuit_dh_prime_data;
178 peer_key.u.dh.base.data = dh_generator_data;
179 peer_key.u.dh.base.len = 1;
180 peer_key.u.dh.publicValue.data = (
unsigned char *)pubkey;
181 peer_key.u.dh.publicValue.len = (int) pubkey_len;
183 PK11SymKey *sym = PK11_PubDerive(dh->seckey, &peer_key,
184 PR_FALSE, NULL, NULL, CKM_DH_PKCS_DERIVE,
185 CKM_GENERIC_SECRET_KEY_GEN ,
186 CKA_DERIVE, 0, NULL);
188 crypto_nss_log_errors(severity,
"deriving a DH shared secret");
192 SECStatus s = PK11_ExtractKeyValue(sym);
193 if (s != SECSuccess) {
194 crypto_nss_log_errors(severity,
"extracting a DH shared secret");
195 PK11_FreeSymKey(sym);
199 SECItem *result = PK11_GetKeyData(sym);
201 if (BUG(result->len > secret_bytes_out)) {
202 PK11_FreeSymKey(sym);
206 ssize_t len = result->len;
207 memcpy(secret_out, result->data, len);
208 PK11_FreeSymKey(sym);
ssize_t crypto_dh_handshake(int severity, crypto_dh_t *dh, const char *pubkey, size_t pubkey_len, unsigned char *secret_out, size_t secret_bytes_out)