sodium_munlock(key, sizeof(key));
}
+DnsCryptQuery::DnsCryptQuery()
+{
+ sodium_mlock(sharedKey, sizeof(sharedKey));
+}
+
+DnsCryptQuery::~DnsCryptQuery()
+{
+ sodium_memzero(sharedKey, sizeof(sharedKey));
+ sodium_munlock(sharedKey, sizeof(sharedKey));
+}
+
void DnsCryptContext::generateProviderKeys(unsigned char publicKey[DNSCRYPT_PROVIDER_PUBLIC_KEY_SIZE], unsigned char privateKey[DNSCRYPT_PROVIDER_PRIVATE_KEY_SIZE])
{
int res = crypto_sign_ed25519_keypair(publicKey, privateKey);
memcpy(nonce, &query->header.clientNonce, sizeof(query->header.clientNonce));
memset(nonce + sizeof(query->header.clientNonce), 0, sizeof(nonce) - sizeof(query->header.clientNonce));
- /* we could compute and store the intermediary shared key, in order to not having to compute it a second
- time for the response:
- - crypto_box_beforenm() into an unsigned char[crypto_box_BEFORENMBYTES]
- - crypto_box_open_easy_afternm()
- - crypto_box_easy_afternm()
- */
- int res = crypto_box_open_easy((unsigned char*) packet,
- (unsigned char*) packet + sizeof(DnsCryptQueryHeader),
- packetSize - sizeof(DnsCryptQueryHeader),
- nonce,
- query->header.clientPK,
- query->useOldCert ? oldPrivateKey.key : privateKey.key);
+ int res = 0;
+ if (!query->sharedKeyComputed) {
+ res = crypto_box_beforenm(query->sharedKey,
+ query->header.clientPK,
+ query->useOldCert ? oldPrivateKey.key : privateKey.key);
+
+ if (res != 0) {
+ vinfolog("Dropping encrypted query we can't compute the shared key for");
+ return;
+ }
+ query->sharedKeyComputed = true;
+ }
+
+ res = crypto_box_open_easy_afternm((unsigned char*) packet,
+ (unsigned char*) packet + sizeof(DnsCryptQueryHeader),
+ packetSize - sizeof(DnsCryptQueryHeader),
+ nonce,
+ query->sharedKey);
if (res != 0) {
vinfolog("Dropping encrypted query we can't decrypt");
pos++;
memset(response + pos, 0, paddingSize - 1);
pos += (paddingSize - 1);
+
/* encrypting */
- int res = crypto_box_easy((unsigned char*) (response + sizeof(header)),
- (unsigned char*) (response + toEncryptPos),
- responseLen + paddingSize,
- header.nonce,
- query->header.clientPK,
- query->useOldCert ? oldPrivateKey.key : privateKey.key);
+ int res = 0;
+ if (!query->sharedKeyComputed) {
+ res = crypto_box_beforenm(query->sharedKey,
+ query->header.clientPK,
+ query->useOldCert ? oldPrivateKey.key : privateKey.key);
+
+ if (res != 0) {
+ return res;
+ }
+ query->sharedKeyComputed = true;
+ }
+
+ res = crypto_box_easy_afternm((unsigned char*) (response + sizeof(header)),
+ (unsigned char*) (response + toEncryptPos),
+ responseLen + paddingSize,
+ header.nonce,
+ query->sharedKey);
if (res == 0) {
assert(pos == requiredSize);