From 413890b3f71cba40db3a307ddf659dc8c586f105 Mon Sep 17 00:00:00 2001
From: Fabian-K <fabian.kajzar@sap.com>
Date: Mon, 17 Aug 2020 10:59:35 +0200
Subject: [PATCH] Plausible Deniability Config Update (EXPOSUREAPP-2214)
 (#1022)

- not trigger a Dummy Playbook for 1% of all clients
- not repeating the playbook pattern for up to 16 days
- not trigger 1-3 repetitions for each communication to CWA/VS
---
 .../coronawarnapp/http/playbook/BackgroundNoise.kt  |  4 +++-
 .../de/rki/coronawarnapp/http/playbook/Playbook.kt  |  5 +++++
 .../rki/coronawarnapp/http/playbook/PlaybookImpl.kt | 13 ++++++-------
 .../service/submission/SubmissionConstants.kt       |  8 ++++----
 .../rki/coronawarnapp/worker/BackgroundConstants.kt |  6 +++---
 5 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt
index 83032127d..ea1005d3d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/BackgroundNoise.kt
@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.http.playbook
 import de.rki.coronawarnapp.http.WebRequestBuilder
 import de.rki.coronawarnapp.service.submission.SubmissionConstants
 import de.rki.coronawarnapp.storage.LocalData
+import de.rki.coronawarnapp.worker.BackgroundConstants
 import de.rki.coronawarnapp.worker.BackgroundWorkScheduler
 import kotlin.random.Random
 
@@ -21,7 +22,8 @@ class BackgroundNoise {
     }
 
     fun scheduleDummyPattern() {
-        BackgroundWorkScheduler.scheduleBackgroundNoisePeriodicWork()
+        if (BackgroundConstants.NUMBER_OF_DAYS_TO_RUN_PLAYBOOK > 0)
+            BackgroundWorkScheduler.scheduleBackgroundNoisePeriodicWork()
     }
 
     suspend fun foregroundScheduleCheck() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt
index 7ed7537bc..66ab1f957 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/Playbook.kt
@@ -4,6 +4,11 @@ import KeyExportFormat
 import de.rki.coronawarnapp.service.submission.KeyType
 import de.rki.coronawarnapp.util.formatter.TestResult
 
+/**
+ * The concept of Plausible Deniability aims to hide the existence of a positive test result by always using a defined “playbook pattern” of requests to the Verification Server and CWA Backend so it is impossible for an attacker to identify which communication was done.
+ * The “playbook pattern” represents a well-defined communication pattern consisting of dummy requests and real requests.
+ * To hide that a real request was done, the device does multiple of these requests over a longer period of time according to the previously defined communication pattern statistically similar to all apps so it is not possible to infer by observing the traffic if the requests under concern are real or the fake ones.
+ */
 interface Playbook {
 
     suspend fun initialRegistration(
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt
index 7ba36966d..3012a1139 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/playbook/PlaybookImpl.kt
@@ -12,7 +12,6 @@ import kotlinx.coroutines.launch
 import timber.log.Timber
 import java.util.UUID
 import java.util.concurrent.TimeUnit
-import kotlin.random.Random
 
 class PlaybookImpl(
     private val webRequestBuilder: WebRequestBuilder
@@ -102,17 +101,17 @@ class PlaybookImpl(
     override suspend fun dummy() = dummy(true)
 
     private suspend fun followUpPlaybooks() {
-        val runsToExecute = Random.nextInt(
-            SubmissionConstants.minNumberOfSequentialPlaybooks,
-            SubmissionConstants.maxNumberOfSequentialPlaybooks
-        )
+        val runsToExecute = IntRange(
+            SubmissionConstants.minNumberOfSequentialPlaybooks - 1 /* one was already executed */,
+            SubmissionConstants.maxNumberOfSequentialPlaybooks - 1 /* one was already executed */
+        ).random()
         Timber.i("[$uid] Follow Up: launching $runsToExecute follow up playbooks")
 
         repeat(runsToExecute) {
-            val executionDelay = Random.nextInt(
+            val executionDelay = IntRange(
                 SubmissionConstants.minDelayBetweenSequentialPlaybooks,
                 SubmissionConstants.maxDelayBetweenSequentialPlaybooks
-            )
+            ).random()
             Timber.i("[$uid] Follow Up: (${it + 1}/$runsToExecute) waiting $executionDelay[s]...")
             delay(TimeUnit.SECONDS.toMillis(executionDelay.toLong()))
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
index eabb63b2f..4ab404508 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
@@ -41,11 +41,11 @@ object SubmissionConstants {
 
     const val PADDING_LENGTH_HEADER_SUBMISSION_FAKE = 36
 
-    const val probabilityToExecutePlaybookWhenOpenApp = 1f
+    const val probabilityToExecutePlaybookWhenOpenApp = 0f
     const val minNumberOfSequentialPlaybooks = 1
-    const val maxNumberOfSequentialPlaybooks = 3
-    const val minDelayBetweenSequentialPlaybooks = 5
-    const val maxDelayBetweenSequentialPlaybooks = 10
+    const val maxNumberOfSequentialPlaybooks = 1
+    const val minDelayBetweenSequentialPlaybooks = 0
+    const val maxDelayBetweenSequentialPlaybooks = 0
 
     const val minKeyCountForSubmission = 14
     const val fakeKeySize = (1 * 16 /* key data*/) + (3 * 4 /* 3x int32*/)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt
index 8f7c14ffa..f15edf556 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/worker/BackgroundConstants.kt
@@ -120,19 +120,19 @@ object BackgroundConstants {
      *
      * @see TimeUnit.HOURS
      */
-    const val MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION = 4L
+    const val MIN_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION = 0L
 
     /**
      * The maximum time in hours to wait between playbook executions
      *
      * @see TimeUnit.HOURS
      */
-    const val MAX_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION = 12L
+    const val MAX_HOURS_TO_NEXT_BACKGROUND_NOISE_EXECUTION = 0L
 
     /**
      * The total time in days to run the playbook
      *
      * @see TimeUnit.DAYS
      */
-    const val NUMBER_OF_DAYS_TO_RUN_PLAYBOOK = 16
+    const val NUMBER_OF_DAYS_TO_RUN_PLAYBOOK = 0
 }
-- 
GitLab